diff --git a/doxygen/input/doc_ssltls.h b/doxygen/input/doc_ssltls.h deleted file mode 100644 index 4addfb38e..000000000 --- a/doxygen/input/doc_ssltls.h +++ /dev/null @@ -1,51 +0,0 @@ -/** - * \file doc_ssltls.h - * - * \brief SSL/TLS communication module documentation file. - */ -/* - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -/** - * @addtogroup ssltls_communication_module SSL/TLS communication module - * - * The SSL/TLS communication module provides the means to create an SSL/TLS - * communication channel. - * - * The basic provisions are: - * - initialise an SSL/TLS context (see \c mbedtls_ssl_init()). - * - perform an SSL/TLS handshake (see \c mbedtls_ssl_handshake()). - * - read/write (see \c mbedtls_ssl_read() and \c mbedtls_ssl_write()). - * - notify a peer that connection is being closed (see \c mbedtls_ssl_close_notify()). - * - * Many aspects of such a channel are set through parameters and callback - * functions: - * - the endpoint role: client or server. - * - the authentication mode. Should verification take place. - * - the Host-to-host communication channel. A TCP/IP module is provided. - * - the random number generator (RNG). - * - the ciphers to use for encryption/decryption. - * - session control functions. - * - X.509 parameters for certificate-handling and key exchange. - * - * This module can be used to create an SSL/TLS server and client and to provide a basic - * framework to setup and communicate through an SSL/TLS communication channel.\n - * Note that you need to provide for several aspects yourself as mentioned above. - */ diff --git a/doxygen/input/doc_tcpip.h b/doxygen/input/doc_tcpip.h deleted file mode 100644 index 95f458601..000000000 --- a/doxygen/input/doc_tcpip.h +++ /dev/null @@ -1,46 +0,0 @@ -/** - * \file doc_tcpip.h - * - * \brief TCP/IP communication module documentation file. - */ -/* - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -/** - * @addtogroup tcpip_communication_module TCP/IP communication module - * - * The TCP/IP communication module provides for a channel of - * communication for the \link ssltls_communication_module SSL/TLS communication - * module\endlink to use. - * In the TCP/IP-model it provides for communication up to the Transport - * (or Host-to-host) layer. - * SSL/TLS resides on top of that, in the Application layer, and makes use of - * its basic provisions: - * - listening on a port (see \c mbedtls_net_bind()). - * - accepting a connection (through \c mbedtls_net_accept()). - * - read/write (through \c mbedtls_net_recv()/\c mbedtls_net_send()). - * - close a connection (through \c mbedtls_net_close()). - * - * This way you have the means to, for example, implement and use an UDP or - * IPSec communication solution as a basis. - * - * This module can be used at server- and clientside to provide a basic - * means of communication over the internet. - */ diff --git a/doxygen/input/doc_x509.h b/doxygen/input/doc_x509.h deleted file mode 100644 index 9b52569bb..000000000 --- a/doxygen/input/doc_x509.h +++ /dev/null @@ -1,45 +0,0 @@ -/** - * \file doc_x509.h - * - * \brief X.509 module documentation file. - */ -/* - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -/** - * @addtogroup x509_module X.509 module - * - * The X.509 module provides X.509 support for reading, writing and verification - * of certificates. - * In summary: - * - X.509 certificate (CRT) reading (see \c mbedtls_x509_crt_parse(), - * \c mbedtls_x509_crt_parse_der(), \c mbedtls_x509_crt_parse_file()). - * - X.509 certificate revocation list (CRL) reading (see - * \c mbedtls_x509_crl_parse(), \c mbedtls_x509_crl_parse_der(), - * and \c mbedtls_x509_crl_parse_file()). - * - X.509 certificate signature verification (see \c - * mbedtls_x509_crt_verify() and \c mbedtls_x509_crt_verify_with_profile(). - * - X.509 certificate writing and certificate request writing (see - * \c mbedtls_x509write_crt_der() and \c mbedtls_x509write_csr_der()). - * - * This module can be used to build a certificate authority (CA) chain and - * verify its signature. It is also used to generate Certificate Signing - * Requests and X.509 certificates just as a CA would do. - */ diff --git a/include/mbedtls/debug.h b/include/mbedtls/debug.h deleted file mode 100644 index 736444bb7..000000000 --- a/include/mbedtls/debug.h +++ /dev/null @@ -1,265 +0,0 @@ -/** - * \file debug.h - * - * \brief Functions for controlling and providing debug output from the library. - */ -/* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -#ifndef MBEDTLS_DEBUG_H -#define MBEDTLS_DEBUG_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "ssl.h" - -#if defined(MBEDTLS_ECP_C) -#include "ecp.h" -#endif - -#if defined(MBEDTLS_DEBUG_C) - -#define MBEDTLS_DEBUG_STRIP_PARENS( ... ) __VA_ARGS__ - -#define MBEDTLS_SSL_DEBUG_MSG( level, args ) \ - mbedtls_debug_print_msg( ssl, level, __FILE__, __LINE__, \ - MBEDTLS_DEBUG_STRIP_PARENS args ) - -#define MBEDTLS_SSL_DEBUG_RET( level, text, ret ) \ - mbedtls_debug_print_ret( ssl, level, __FILE__, __LINE__, text, ret ) - -#define MBEDTLS_SSL_DEBUG_BUF( level, text, buf, len ) \ - mbedtls_debug_print_buf( ssl, level, __FILE__, __LINE__, text, buf, len ) - -#if defined(MBEDTLS_BIGNUM_C) -#define MBEDTLS_SSL_DEBUG_MPI( level, text, X ) \ - mbedtls_debug_print_mpi( ssl, level, __FILE__, __LINE__, text, X ) -#endif - -#if defined(MBEDTLS_ECP_C) -#define MBEDTLS_SSL_DEBUG_ECP( level, text, X ) \ - mbedtls_debug_print_ecp( ssl, level, __FILE__, __LINE__, text, X ) -#endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -#define MBEDTLS_SSL_DEBUG_CRT( level, text, crt ) \ - mbedtls_debug_print_crt( ssl, level, __FILE__, __LINE__, text, crt ) -#endif - -#if defined(MBEDTLS_ECDH_C) -#define MBEDTLS_SSL_DEBUG_ECDH( level, ecdh, attr ) \ - mbedtls_debug_printf_ecdh( ssl, level, __FILE__, __LINE__, ecdh, attr ) -#endif - -#else /* MBEDTLS_DEBUG_C */ - -#define MBEDTLS_SSL_DEBUG_MSG( level, args ) do { } while( 0 ) -#define MBEDTLS_SSL_DEBUG_RET( level, text, ret ) do { } while( 0 ) -#define MBEDTLS_SSL_DEBUG_BUF( level, text, buf, len ) do { } while( 0 ) -#define MBEDTLS_SSL_DEBUG_MPI( level, text, X ) do { } while( 0 ) -#define MBEDTLS_SSL_DEBUG_ECP( level, text, X ) do { } while( 0 ) -#define MBEDTLS_SSL_DEBUG_CRT( level, text, crt ) do { } while( 0 ) -#define MBEDTLS_SSL_DEBUG_ECDH( level, ecdh, attr ) do { } while( 0 ) - -#endif /* MBEDTLS_DEBUG_C */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Set the threshold error level to handle globally all debug output. - * Debug messages that have a level over the threshold value are - * discarded. - * (Default value: 0 = No debug ) - * - * \param threshold theshold level of messages to filter on. Messages at a - * higher level will be discarded. - * - Debug levels - * - 0 No debug - * - 1 Error - * - 2 State change - * - 3 Informational - * - 4 Verbose - */ -void mbedtls_debug_set_threshold( int threshold ); - -/** - * \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, ... ); - -/** - * \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. This function is always - * used through the MBEDTLS_SSL_DEBUG_MPI() 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 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_ECP_C) -/** - * \brief Print an ECP point to the debug output. This function is always - * used through the MBEDTLS_SSL_DEBUG_ECP() 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 ECP point being output. Normally the - * variable name - * \param X the ECP point - * - * \attention This function is intended for INTERNAL usage within the - * library only. - */ -void mbedtls_debug_print_ecp( const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const char *text, const mbedtls_ecp_point *X ); -#endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -/** - * \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 - -#if defined(MBEDTLS_ECDH_C) -typedef enum -{ - MBEDTLS_DEBUG_ECDH_Q, - MBEDTLS_DEBUG_ECDH_QP, - MBEDTLS_DEBUG_ECDH_Z, -} mbedtls_debug_ecdh_attr; - -/** - * \brief Print a field of the ECDH structure in the SSL context to the debug - * output. This function is always used through the - * MBEDTLS_SSL_DEBUG_ECDH() 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 ecdh the ECDH context - * \param attr the identifier of the attribute being output - * - * \attention This function is intended for INTERNAL usage within the - * library only. - */ -void mbedtls_debug_printf_ecdh( const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const mbedtls_ecdh_context *ecdh, - mbedtls_debug_ecdh_attr attr ); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* debug.h */ - diff --git a/include/mbedtls/net.h b/include/mbedtls/net.h deleted file mode 100644 index 8cead58e5..000000000 --- a/include/mbedtls/net.h +++ /dev/null @@ -1,37 +0,0 @@ -/** - * \file net.h - * - * \brief Deprecated header file that includes net_sockets.h - * - * \deprecated Superseded by mbedtls/net_sockets.h - */ -/* - * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -#include "net_sockets.h" -#if defined(MBEDTLS_DEPRECATED_WARNING) -#warning "Deprecated header file: Superseded by mbedtls/net_sockets.h" -#endif /* MBEDTLS_DEPRECATED_WARNING */ -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ diff --git a/include/mbedtls/net_sockets.h b/include/mbedtls/net_sockets.h deleted file mode 100644 index 4c7ef00fe..000000000 --- a/include/mbedtls/net_sockets.h +++ /dev/null @@ -1,271 +0,0 @@ -/** - * \file net_sockets.h - * - * \brief Network sockets abstraction layer to integrate Mbed TLS into a - * BSD-style sockets API. - * - * The network sockets module provides an example integration of the - * Mbed TLS library into a BSD sockets implementation. The module is - * intended to be an example of how Mbed TLS can be integrated into a - * networking stack, as well as to be Mbed TLS's network integration - * for its supported platforms. - * - * The module is intended only to be used with the Mbed TLS library and - * is not intended to be used by third party application software - * directly. - * - * The supported platforms are as follows: - * * Microsoft Windows and Windows CE - * * POSIX/Unix platforms including Linux, OS X - * - */ -/* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -#ifndef MBEDTLS_NET_SOCKETS_H -#define MBEDTLS_NET_SOCKETS_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "ssl.h" - -#include -#include - -#define MBEDTLS_ERR_NET_SOCKET_FAILED -0x0042 /**< Failed to open a socket. */ -#define MBEDTLS_ERR_NET_CONNECT_FAILED -0x0044 /**< The connection to the given server / port failed. */ -#define MBEDTLS_ERR_NET_BIND_FAILED -0x0046 /**< Binding of the socket failed. */ -#define MBEDTLS_ERR_NET_LISTEN_FAILED -0x0048 /**< Could not listen on the socket. */ -#define MBEDTLS_ERR_NET_ACCEPT_FAILED -0x004A /**< Could not accept the incoming connection. */ -#define MBEDTLS_ERR_NET_RECV_FAILED -0x004C /**< Reading information from the socket failed. */ -#define MBEDTLS_ERR_NET_SEND_FAILED -0x004E /**< Sending information through the socket failed. */ -#define MBEDTLS_ERR_NET_CONN_RESET -0x0050 /**< Connection was reset by peer. */ -#define MBEDTLS_ERR_NET_UNKNOWN_HOST -0x0052 /**< Failed to get an IP address for the given hostname. */ -#define MBEDTLS_ERR_NET_BUFFER_TOO_SMALL -0x0043 /**< Buffer is too small to hold the data. */ -#define MBEDTLS_ERR_NET_INVALID_CONTEXT -0x0045 /**< The context is invalid, eg because it was free()ed. */ -#define MBEDTLS_ERR_NET_POLL_FAILED -0x0047 /**< Polling the net context failed. */ -#define MBEDTLS_ERR_NET_BAD_INPUT_DATA -0x0049 /**< Input invalid. */ - -#define MBEDTLS_NET_LISTEN_BACKLOG 10 /**< The backlog that listen() should use. */ - -#define MBEDTLS_NET_PROTO_TCP 0 /**< The TCP transport protocol */ -#define MBEDTLS_NET_PROTO_UDP 1 /**< The UDP transport protocol */ - -#define MBEDTLS_NET_POLL_READ 1 /**< Used in \c mbedtls_net_poll to check for pending data */ -#define MBEDTLS_NET_POLL_WRITE 2 /**< Used in \c mbedtls_net_poll to check if write possible */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Wrapper type for sockets. - * - * Currently backed by just a file descriptor, but might be more in the future - * (eg two file descriptors for combined IPv4 + IPv6 support, or additional - * structures for hand-made UDP demultiplexing). - */ -typedef struct mbedtls_net_context -{ - int fd; /**< The underlying file descriptor */ -} -mbedtls_net_context; - -/** - * \brief Initialize a context - * Just makes the context ready to be used or freed safely. - * - * \param ctx Context to initialize - */ -void mbedtls_net_init( mbedtls_net_context *ctx ); - -/** - * \brief Initiate a connection with host:port in the given protocol - * - * \param ctx Socket to use - * \param host Host to connect to - * \param port Port to connect to - * \param proto Protocol: MBEDTLS_NET_PROTO_TCP or MBEDTLS_NET_PROTO_UDP - * - * \return 0 if successful, or one of: - * MBEDTLS_ERR_NET_SOCKET_FAILED, - * MBEDTLS_ERR_NET_UNKNOWN_HOST, - * MBEDTLS_ERR_NET_CONNECT_FAILED - * - * \note Sets the socket in connected mode even with UDP. - */ -int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host, const char *port, int proto ); - -/** - * \brief Create a receiving socket on bind_ip:port in the chosen - * protocol. If bind_ip == NULL, all interfaces are bound. - * - * \param ctx Socket to use - * \param bind_ip IP to bind to, can be NULL - * \param port Port number to use - * \param proto Protocol: MBEDTLS_NET_PROTO_TCP or MBEDTLS_NET_PROTO_UDP - * - * \return 0 if successful, or one of: - * MBEDTLS_ERR_NET_SOCKET_FAILED, - * MBEDTLS_ERR_NET_BIND_FAILED, - * MBEDTLS_ERR_NET_LISTEN_FAILED - * - * \note Regardless of the protocol, opens the sockets and binds it. - * In addition, make the socket listening if protocol is TCP. - */ -int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char *port, int proto ); - -/** - * \brief Accept a connection from a remote client - * - * \param bind_ctx Relevant socket - * \param client_ctx Will contain the connected client socket - * \param client_ip Will contain the client IP address, can be NULL - * \param buf_size Size of the client_ip buffer - * \param ip_len Will receive the size of the client IP written, - * can be NULL if client_ip is null - * - * \return 0 if successful, or - * MBEDTLS_ERR_NET_ACCEPT_FAILED, or - * MBEDTLS_ERR_NET_BUFFER_TOO_SMALL if buf_size is too small, - * MBEDTLS_ERR_SSL_WANT_READ if bind_fd was set to - * non-blocking and accept() would block. - */ -int mbedtls_net_accept( mbedtls_net_context *bind_ctx, - mbedtls_net_context *client_ctx, - void *client_ip, size_t buf_size, size_t *ip_len ); - -/** - * \brief Check and wait for the context to be ready for read/write - * - * \param ctx Socket to check - * \param rw Bitflag composed of MBEDTLS_NET_POLL_READ and - * MBEDTLS_NET_POLL_WRITE specifying the events - * to wait for: - * - If MBEDTLS_NET_POLL_READ is set, the function - * will return as soon as the net context is available - * for reading. - * - If MBEDTLS_NET_POLL_WRITE is set, the function - * will return as soon as the net context is available - * for writing. - * \param timeout Maximal amount of time to wait before returning, - * in milliseconds. If \c timeout is zero, the - * function returns immediately. If \c timeout is - * -1u, the function blocks potentially indefinitely. - * - * \return Bitmask composed of MBEDTLS_NET_POLL_READ/WRITE - * on success or timeout, or a negative return code otherwise. - */ -int mbedtls_net_poll( mbedtls_net_context *ctx, uint32_t rw, uint32_t timeout ); - -/** - * \brief Set the socket blocking - * - * \param ctx Socket to set - * - * \return 0 if successful, or a non-zero error code - */ -int mbedtls_net_set_block( mbedtls_net_context *ctx ); - -/** - * \brief Set the socket non-blocking - * - * \param ctx Socket to set - * - * \return 0 if successful, or a non-zero error code - */ -int mbedtls_net_set_nonblock( mbedtls_net_context *ctx ); - -/** - * \brief Portable usleep helper - * - * \param usec Amount of microseconds to sleep - * - * \note Real amount of time slept will not be less than - * select()'s timeout granularity (typically, 10ms). - */ -void mbedtls_net_usleep( unsigned long usec ); - -/** - * \brief Read at most 'len' characters. If no error occurs, - * the actual amount read is returned. - * - * \param ctx Socket - * \param buf The buffer to write to - * \param len Maximum length of the buffer - * - * \return the number of bytes received, - * or a non-zero error code; with a non-blocking socket, - * MBEDTLS_ERR_SSL_WANT_READ indicates read() would block. - */ -int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len ); - -/** - * \brief Write at most 'len' characters. If no error occurs, - * the actual amount read is returned. - * - * \param ctx Socket - * \param buf The buffer to read from - * \param len The length of the buffer - * - * \return the number of bytes sent, - * or a non-zero error code; with a non-blocking socket, - * MBEDTLS_ERR_SSL_WANT_WRITE indicates write() would block. - */ -int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len ); - -/** - * \brief Read at most 'len' characters, blocking for at most - * 'timeout' seconds. If no error occurs, the actual amount - * read is returned. - * - * \param ctx Socket - * \param buf The buffer to write to - * \param len Maximum length of the buffer - * \param timeout Maximum number of milliseconds to wait for data - * 0 means no timeout (wait forever) - * - * \return the number of bytes received, - * or a non-zero error code: - * MBEDTLS_ERR_SSL_TIMEOUT if the operation timed out, - * MBEDTLS_ERR_SSL_WANT_READ if interrupted by a signal. - * - * \note This function will block (until data becomes available or - * timeout is reached) even if the socket is set to - * non-blocking. Handling timeouts with non-blocking reads - * requires a different strategy. - */ -int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len, - uint32_t timeout ); - -/** - * \brief Gracefully shutdown the connection and free associated data - * - * \param ctx The context to free - */ -void mbedtls_net_free( mbedtls_net_context *ctx ); - -#ifdef __cplusplus -} -#endif - -#endif /* net_sockets.h */ diff --git a/include/mbedtls/pkcs11.h b/include/mbedtls/pkcs11.h deleted file mode 100644 index 02427ddc1..000000000 --- a/include/mbedtls/pkcs11.h +++ /dev/null @@ -1,175 +0,0 @@ -/** - * \file pkcs11.h - * - * \brief Wrapper for PKCS#11 library libpkcs11-helper - * - * \author Adriaan de Jong - */ -/* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -#ifndef MBEDTLS_PKCS11_H -#define MBEDTLS_PKCS11_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_PKCS11_C) - -#include "x509_crt.h" - -#include - -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Context for PKCS #11 private keys. - */ -typedef struct mbedtls_pkcs11_context -{ - pkcs11h_certificate_t pkcs11h_cert; - int len; -} mbedtls_pkcs11_context; - -/** - * Initialize a mbedtls_pkcs11_context. - * (Just making memory references valid.) - */ -void mbedtls_pkcs11_init( mbedtls_pkcs11_context *ctx ); - -/** - * Fill in a mbed TLS certificate, based on the given PKCS11 helper certificate. - * - * \param cert X.509 certificate to fill - * \param pkcs11h_cert PKCS #11 helper certificate - * - * \return 0 on success. - */ -int mbedtls_pkcs11_x509_cert_bind( mbedtls_x509_crt *cert, pkcs11h_certificate_t pkcs11h_cert ); - -/** - * Set up a mbedtls_pkcs11_context storing the given certificate. Note that the - * mbedtls_pkcs11_context will take over control of the certificate, freeing it when - * done. - * - * \param priv_key Private key structure to fill. - * \param pkcs11_cert PKCS #11 helper certificate - * - * \return 0 on success - */ -int mbedtls_pkcs11_priv_key_bind( mbedtls_pkcs11_context *priv_key, - pkcs11h_certificate_t pkcs11_cert ); - -/** - * Free the contents of the given private key context. Note that the structure - * itself is not freed. - * - * \param priv_key Private key structure to cleanup - */ -void mbedtls_pkcs11_priv_key_free( mbedtls_pkcs11_context *priv_key ); - -/** - * \brief Do an RSA private key decrypt, then remove the message - * padding - * - * \param ctx PKCS #11 context - * \param mode must be MBEDTLS_RSA_PRIVATE, for compatibility with rsa.c's signature - * \param input buffer holding the encrypted data - * \param output buffer that will hold the plaintext - * \param olen will contain the plaintext length - * \param output_max_len maximum length of the output buffer - * - * \return 0 if successful, or an MBEDTLS_ERR_RSA_XXX error code - * - * \note The output buffer must be as large as the size - * of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise - * an error is thrown. - */ -int mbedtls_pkcs11_decrypt( mbedtls_pkcs11_context *ctx, - int mode, size_t *olen, - const unsigned char *input, - unsigned char *output, - size_t output_max_len ); - -/** - * \brief Do a private RSA to sign a message digest - * - * \param ctx PKCS #11 context - * \param mode must be MBEDTLS_RSA_PRIVATE, for compatibility with rsa.c's signature - * \param md_alg a MBEDTLS_MD_XXX (use MBEDTLS_MD_NONE for signing raw data) - * \param hashlen message digest length (for MBEDTLS_MD_NONE only) - * \param hash buffer holding the message digest - * \param sig buffer that will hold the ciphertext - * - * \return 0 if the signing operation was successful, - * or an MBEDTLS_ERR_RSA_XXX error code - * - * \note The "sig" buffer must be as large as the size - * of ctx->N (eg. 128 bytes if RSA-1024 is used). - */ -int mbedtls_pkcs11_sign( mbedtls_pkcs11_context *ctx, - int mode, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - unsigned char *sig ); - -/** - * SSL/TLS wrappers for PKCS#11 functions - */ -static inline int mbedtls_ssl_pkcs11_decrypt( void *ctx, int mode, size_t *olen, - const unsigned char *input, unsigned char *output, - size_t output_max_len ) -{ - return mbedtls_pkcs11_decrypt( (mbedtls_pkcs11_context *) ctx, mode, olen, input, output, - output_max_len ); -} - -static inline int mbedtls_ssl_pkcs11_sign( void *ctx, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - int mode, mbedtls_md_type_t md_alg, unsigned int hashlen, - const unsigned char *hash, unsigned char *sig ) -{ - ((void) f_rng); - ((void) p_rng); - return mbedtls_pkcs11_sign( (mbedtls_pkcs11_context *) ctx, mode, md_alg, - hashlen, hash, sig ); -} - -static inline size_t mbedtls_ssl_pkcs11_key_len( void *ctx ) -{ - return ( (mbedtls_pkcs11_context *) ctx )->len; -} - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_PKCS11_C */ - -#endif /* MBEDTLS_PKCS11_H */ diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h deleted file mode 100644 index 135be0501..000000000 --- a/include/mbedtls/ssl.h +++ /dev/null @@ -1,3494 +0,0 @@ -/** - * \file ssl.h - * - * \brief SSL/TLS functions. - */ -/* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -#ifndef MBEDTLS_SSL_H -#define MBEDTLS_SSL_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "bignum.h" -#include "ecp.h" - -#include "ssl_ciphersuites.h" - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -#include "x509_crt.h" -#include "x509_crl.h" -#endif - -#if defined(MBEDTLS_DHM_C) -#include "dhm.h" -#endif - -#if defined(MBEDTLS_ECDH_C) -#include "ecdh.h" -#endif - -#if defined(MBEDTLS_ZLIB_SUPPORT) - -#if defined(MBEDTLS_DEPRECATED_WARNING) -#warning "Record compression support via MBEDTLS_ZLIB_SUPPORT is deprecated and will be removed in the next major revision of the library" -#endif - -#if defined(MBEDTLS_DEPRECATED_REMOVED) -#error "Record compression support via MBEDTLS_ZLIB_SUPPORT is deprecated and cannot be used if MBEDTLS_DEPRECATED_REMOVED is set" -#endif - -#include "zlib.h" -#endif - -#if defined(MBEDTLS_HAVE_TIME) -#include "platform_time.h" -#endif - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "psa/crypto.h" -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -/* - * SSL Error codes - */ -#define MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE -0x7080 /**< The requested feature is not available. */ -#define MBEDTLS_ERR_SSL_BAD_INPUT_DATA -0x7100 /**< Bad input parameters to function. */ -#define MBEDTLS_ERR_SSL_INVALID_MAC -0x7180 /**< Verification of the message MAC failed. */ -#define MBEDTLS_ERR_SSL_INVALID_RECORD -0x7200 /**< An invalid SSL record was received. */ -#define MBEDTLS_ERR_SSL_CONN_EOF -0x7280 /**< The connection indicated an EOF. */ -#define MBEDTLS_ERR_SSL_UNKNOWN_CIPHER -0x7300 /**< An unknown cipher was received. */ -#define MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN -0x7380 /**< The server has no ciphersuites in common with the client. */ -#define MBEDTLS_ERR_SSL_NO_RNG -0x7400 /**< No RNG was provided to the SSL module. */ -#define MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE -0x7480 /**< No client certification received from the client, but required by the authentication mode. */ -#define MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE -0x7500 /**< Our own certificate(s) is/are too large to send in an SSL message. */ -#define MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED -0x7580 /**< The own certificate is not set, but needed by the server. */ -#define MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED -0x7600 /**< The own private key or pre-shared key is not set, but needed. */ -#define MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED -0x7680 /**< No CA Chain is set, but required to operate. */ -#define MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE -0x7700 /**< An unexpected message was received from our peer. */ -#define MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE -0x7780 /**< A fatal alert message was received from our peer. */ -#define MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED -0x7800 /**< Verification of our peer failed. */ -#define MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY -0x7880 /**< The peer notified us that the connection is going to be closed. */ -#define MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO -0x7900 /**< Processing of the ClientHello handshake message failed. */ -#define MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO -0x7980 /**< Processing of the ServerHello handshake message failed. */ -#define MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE -0x7A00 /**< Processing of the Certificate handshake message failed. */ -#define MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST -0x7A80 /**< Processing of the CertificateRequest handshake message failed. */ -#define MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE -0x7B00 /**< Processing of the ServerKeyExchange handshake message failed. */ -#define MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE -0x7B80 /**< Processing of the ServerHelloDone handshake message failed. */ -#define MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE -0x7C00 /**< Processing of the ClientKeyExchange handshake message failed. */ -#define MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP -0x7C80 /**< Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Read Public. */ -#define MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS -0x7D00 /**< Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Calculate Secret. */ -#define MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY -0x7D80 /**< Processing of the CertificateVerify handshake message failed. */ -#define MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC -0x7E00 /**< Processing of the ChangeCipherSpec handshake message failed. */ -#define MBEDTLS_ERR_SSL_BAD_HS_FINISHED -0x7E80 /**< Processing of the Finished handshake message failed. */ -#define MBEDTLS_ERR_SSL_ALLOC_FAILED -0x7F00 /**< Memory allocation failed */ -#define MBEDTLS_ERR_SSL_HW_ACCEL_FAILED -0x7F80 /**< Hardware acceleration function returned with error */ -#define MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH -0x6F80 /**< Hardware acceleration function skipped / left alone data */ -#define MBEDTLS_ERR_SSL_COMPRESSION_FAILED -0x6F00 /**< Processing of the compression / decompression failed */ -#define MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION -0x6E80 /**< Handshake protocol not within min/max boundaries */ -#define MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET -0x6E00 /**< Processing of the NewSessionTicket handshake message failed. */ -#define MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED -0x6D80 /**< Session ticket has expired. */ -#define MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH -0x6D00 /**< Public key type mismatch (eg, asked for RSA key exchange and presented EC key) */ -#define MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY -0x6C80 /**< Unknown identity received (eg, PSK identity) */ -#define MBEDTLS_ERR_SSL_INTERNAL_ERROR -0x6C00 /**< Internal error (eg, unexpected failure in lower-level module) */ -#define MBEDTLS_ERR_SSL_COUNTER_WRAPPING -0x6B80 /**< A counter would wrap (eg, too many messages exchanged). */ -#define MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO -0x6B00 /**< Unexpected message at ServerHello in renegotiation. */ -#define MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED -0x6A80 /**< DTLS client must retry for hello verification */ -#define MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL -0x6A00 /**< A buffer is too small to receive or write a message */ -#define MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE -0x6980 /**< None of the common ciphersuites is usable (eg, no suitable certificate, see debug messages). */ -#define MBEDTLS_ERR_SSL_WANT_READ -0x6900 /**< No data of requested type currently available on underlying transport. */ -#define MBEDTLS_ERR_SSL_WANT_WRITE -0x6880 /**< Connection requires a write call. */ -#define MBEDTLS_ERR_SSL_TIMEOUT -0x6800 /**< The operation timed out. */ -#define MBEDTLS_ERR_SSL_CLIENT_RECONNECT -0x6780 /**< The client initiated a reconnect from the same port. */ -#define MBEDTLS_ERR_SSL_UNEXPECTED_RECORD -0x6700 /**< Record header looks valid but is not expected. */ -#define MBEDTLS_ERR_SSL_NON_FATAL -0x6680 /**< The alert message received indicates a non-fatal error. */ -#define MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH -0x6600 /**< Couldn't set the hash for verifying CertificateVerify */ -#define MBEDTLS_ERR_SSL_CONTINUE_PROCESSING -0x6580 /**< Internal-only message signaling that further message-processing should be done */ -#define MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS -0x6500 /**< The asynchronous operation is not completed yet. */ -#define MBEDTLS_ERR_SSL_EARLY_MESSAGE -0x6480 /**< Internal-only message signaling that a message arrived early. */ -#define MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS -0x7000 /**< A cryptographic operation is in progress. Try again later. */ - -/* - * Various constants - */ -#define MBEDTLS_SSL_MAJOR_VERSION_3 3 -#define MBEDTLS_SSL_MINOR_VERSION_0 0 /*!< SSL v3.0 */ -#define MBEDTLS_SSL_MINOR_VERSION_1 1 /*!< TLS v1.0 */ -#define MBEDTLS_SSL_MINOR_VERSION_2 2 /*!< TLS v1.1 */ -#define MBEDTLS_SSL_MINOR_VERSION_3 3 /*!< TLS v1.2 */ - -#define MBEDTLS_SSL_TRANSPORT_STREAM 0 /*!< TLS */ -#define MBEDTLS_SSL_TRANSPORT_DATAGRAM 1 /*!< DTLS */ - -#define MBEDTLS_SSL_MAX_HOST_NAME_LEN 255 /*!< Maximum host name defined in RFC 1035 */ - -/* RFC 6066 section 4, see also mfl_code_to_length in ssl_tls.c - * NONE must be zero so that memset()ing structure to zero works */ -#define MBEDTLS_SSL_MAX_FRAG_LEN_NONE 0 /*!< don't use this extension */ -#define MBEDTLS_SSL_MAX_FRAG_LEN_512 1 /*!< MaxFragmentLength 2^9 */ -#define MBEDTLS_SSL_MAX_FRAG_LEN_1024 2 /*!< MaxFragmentLength 2^10 */ -#define MBEDTLS_SSL_MAX_FRAG_LEN_2048 3 /*!< MaxFragmentLength 2^11 */ -#define MBEDTLS_SSL_MAX_FRAG_LEN_4096 4 /*!< MaxFragmentLength 2^12 */ -#define MBEDTLS_SSL_MAX_FRAG_LEN_INVALID 5 /*!< first invalid value */ - -#define MBEDTLS_SSL_IS_CLIENT 0 -#define MBEDTLS_SSL_IS_SERVER 1 - -#define MBEDTLS_SSL_IS_NOT_FALLBACK 0 -#define MBEDTLS_SSL_IS_FALLBACK 1 - -#define MBEDTLS_SSL_EXTENDED_MS_DISABLED 0 -#define MBEDTLS_SSL_EXTENDED_MS_ENABLED 1 - -#define MBEDTLS_SSL_ETM_DISABLED 0 -#define MBEDTLS_SSL_ETM_ENABLED 1 - -#define MBEDTLS_SSL_COMPRESS_NULL 0 -#define MBEDTLS_SSL_COMPRESS_DEFLATE 1 - -#define MBEDTLS_SSL_VERIFY_NONE 0 -#define MBEDTLS_SSL_VERIFY_OPTIONAL 1 -#define MBEDTLS_SSL_VERIFY_REQUIRED 2 -#define MBEDTLS_SSL_VERIFY_UNSET 3 /* Used only for sni_authmode */ - -#define MBEDTLS_SSL_LEGACY_RENEGOTIATION 0 -#define MBEDTLS_SSL_SECURE_RENEGOTIATION 1 - -#define MBEDTLS_SSL_RENEGOTIATION_DISABLED 0 -#define MBEDTLS_SSL_RENEGOTIATION_ENABLED 1 - -#define MBEDTLS_SSL_ANTI_REPLAY_DISABLED 0 -#define MBEDTLS_SSL_ANTI_REPLAY_ENABLED 1 - -#define MBEDTLS_SSL_RENEGOTIATION_NOT_ENFORCED -1 -#define MBEDTLS_SSL_RENEGO_MAX_RECORDS_DEFAULT 16 - -#define MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION 0 -#define MBEDTLS_SSL_LEGACY_ALLOW_RENEGOTIATION 1 -#define MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE 2 - -#define MBEDTLS_SSL_TRUNC_HMAC_DISABLED 0 -#define MBEDTLS_SSL_TRUNC_HMAC_ENABLED 1 -#define MBEDTLS_SSL_TRUNCATED_HMAC_LEN 10 /* 80 bits, rfc 6066 section 7 */ - -#define MBEDTLS_SSL_SESSION_TICKETS_DISABLED 0 -#define MBEDTLS_SSL_SESSION_TICKETS_ENABLED 1 - -#define MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED 0 -#define MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED 1 - -#define MBEDTLS_SSL_ARC4_ENABLED 0 -#define MBEDTLS_SSL_ARC4_DISABLED 1 - -#define MBEDTLS_SSL_PRESET_DEFAULT 0 -#define MBEDTLS_SSL_PRESET_SUITEB 2 - -#define MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED 1 -#define MBEDTLS_SSL_CERT_REQ_CA_LIST_DISABLED 0 - -/* - * Default range for DTLS retransmission timer value, in milliseconds. - * RFC 6347 4.2.4.1 says from 1 second to 60 seconds. - */ -#define MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN 1000 -#define MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MAX 60000 - -/** - * \name SECTION: Module settings - * - * The configuration options you can set for this module are in this section. - * Either change them in config.h or define them on the compiler command line. - * \{ - */ - -#if !defined(MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME) -#define MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */ -#endif - -/* - * Maximum fragment length in bytes, - * determines the size of each of the two internal I/O buffers. - * - * Note: the RFC defines the default size of SSL / TLS messages. If you - * change the value here, other clients / servers may not be able to - * communicate with you anymore. Only change this value if you control - * both sides of the connection and have it reduced at both sides, or - * if you're using the Max Fragment Length extension and you know all your - * peers are using it too! - */ -#if !defined(MBEDTLS_SSL_MAX_CONTENT_LEN) -#define MBEDTLS_SSL_MAX_CONTENT_LEN 16384 /**< Size of the input / output buffer */ -#endif - -#if !defined(MBEDTLS_SSL_IN_CONTENT_LEN) -#define MBEDTLS_SSL_IN_CONTENT_LEN MBEDTLS_SSL_MAX_CONTENT_LEN -#endif - -#if !defined(MBEDTLS_SSL_OUT_CONTENT_LEN) -#define MBEDTLS_SSL_OUT_CONTENT_LEN MBEDTLS_SSL_MAX_CONTENT_LEN -#endif - -/* - * Maximum number of heap-allocated bytes for the purpose of - * DTLS handshake message reassembly and future message buffering. - */ -#if !defined(MBEDTLS_SSL_DTLS_MAX_BUFFERING) -#define MBEDTLS_SSL_DTLS_MAX_BUFFERING 32768 -#endif - -/* \} name SECTION: Module settings */ - -/* - * Length of the verify data for secure renegotiation - */ -#if defined(MBEDTLS_SSL_PROTO_SSL3) -#define MBEDTLS_SSL_VERIFY_DATA_MAX_LEN 36 -#else -#define MBEDTLS_SSL_VERIFY_DATA_MAX_LEN 12 -#endif - -/* - * Signaling ciphersuite values (SCSV) - */ -#define MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO 0xFF /**< renegotiation info ext */ -#define MBEDTLS_SSL_FALLBACK_SCSV_VALUE 0x5600 /**< RFC 7507 section 2 */ - -/* - * Supported Signature and Hash algorithms (For TLS 1.2) - * RFC 5246 section 7.4.1.4.1 - */ -#define MBEDTLS_SSL_HASH_NONE 0 -#define MBEDTLS_SSL_HASH_MD5 1 -#define MBEDTLS_SSL_HASH_SHA1 2 -#define MBEDTLS_SSL_HASH_SHA224 3 -#define MBEDTLS_SSL_HASH_SHA256 4 -#define MBEDTLS_SSL_HASH_SHA384 5 -#define MBEDTLS_SSL_HASH_SHA512 6 - -#define MBEDTLS_SSL_SIG_ANON 0 -#define MBEDTLS_SSL_SIG_RSA 1 -#define MBEDTLS_SSL_SIG_ECDSA 3 - -/* - * Client Certificate Types - * RFC 5246 section 7.4.4 plus RFC 4492 section 5.5 - */ -#define MBEDTLS_SSL_CERT_TYPE_RSA_SIGN 1 -#define MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN 64 - -/* - * Message, alert and handshake types - */ -#define MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC 20 -#define MBEDTLS_SSL_MSG_ALERT 21 -#define MBEDTLS_SSL_MSG_HANDSHAKE 22 -#define MBEDTLS_SSL_MSG_APPLICATION_DATA 23 - -#define MBEDTLS_SSL_ALERT_LEVEL_WARNING 1 -#define MBEDTLS_SSL_ALERT_LEVEL_FATAL 2 - -#define MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY 0 /* 0x00 */ -#define MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE 10 /* 0x0A */ -#define MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC 20 /* 0x14 */ -#define MBEDTLS_SSL_ALERT_MSG_DECRYPTION_FAILED 21 /* 0x15 */ -#define MBEDTLS_SSL_ALERT_MSG_RECORD_OVERFLOW 22 /* 0x16 */ -#define MBEDTLS_SSL_ALERT_MSG_DECOMPRESSION_FAILURE 30 /* 0x1E */ -#define MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE 40 /* 0x28 */ -#define MBEDTLS_SSL_ALERT_MSG_NO_CERT 41 /* 0x29 */ -#define MBEDTLS_SSL_ALERT_MSG_BAD_CERT 42 /* 0x2A */ -#define MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT 43 /* 0x2B */ -#define MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED 44 /* 0x2C */ -#define MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED 45 /* 0x2D */ -#define MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN 46 /* 0x2E */ -#define MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER 47 /* 0x2F */ -#define MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA 48 /* 0x30 */ -#define MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED 49 /* 0x31 */ -#define MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR 50 /* 0x32 */ -#define MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR 51 /* 0x33 */ -#define MBEDTLS_SSL_ALERT_MSG_EXPORT_RESTRICTION 60 /* 0x3C */ -#define MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION 70 /* 0x46 */ -#define MBEDTLS_SSL_ALERT_MSG_INSUFFICIENT_SECURITY 71 /* 0x47 */ -#define MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR 80 /* 0x50 */ -#define MBEDTLS_SSL_ALERT_MSG_INAPROPRIATE_FALLBACK 86 /* 0x56 */ -#define MBEDTLS_SSL_ALERT_MSG_USER_CANCELED 90 /* 0x5A */ -#define MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION 100 /* 0x64 */ -#define MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT 110 /* 0x6E */ -#define MBEDTLS_SSL_ALERT_MSG_UNRECOGNIZED_NAME 112 /* 0x70 */ -#define MBEDTLS_SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY 115 /* 0x73 */ -#define MBEDTLS_SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL 120 /* 0x78 */ - -#define MBEDTLS_SSL_HS_HELLO_REQUEST 0 -#define MBEDTLS_SSL_HS_CLIENT_HELLO 1 -#define MBEDTLS_SSL_HS_SERVER_HELLO 2 -#define MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST 3 -#define MBEDTLS_SSL_HS_NEW_SESSION_TICKET 4 -#define MBEDTLS_SSL_HS_CERTIFICATE 11 -#define MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE 12 -#define MBEDTLS_SSL_HS_CERTIFICATE_REQUEST 13 -#define MBEDTLS_SSL_HS_SERVER_HELLO_DONE 14 -#define MBEDTLS_SSL_HS_CERTIFICATE_VERIFY 15 -#define MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE 16 -#define MBEDTLS_SSL_HS_FINISHED 20 - -/* - * TLS extensions - */ -#define MBEDTLS_TLS_EXT_SERVERNAME 0 -#define MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME 0 - -#define MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH 1 - -#define MBEDTLS_TLS_EXT_TRUNCATED_HMAC 4 - -#define MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES 10 -#define MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS 11 - -#define MBEDTLS_TLS_EXT_SIG_ALG 13 - -#define MBEDTLS_TLS_EXT_ALPN 16 - -#define MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC 22 /* 0x16 */ -#define MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET 0x0017 /* 23 */ - -#define MBEDTLS_TLS_EXT_SESSION_TICKET 35 - -#define MBEDTLS_TLS_EXT_ECJPAKE_KKPP 256 /* experimental */ - -#define MBEDTLS_TLS_EXT_RENEGOTIATION_INFO 0xFF01 - -/* - * Size defines - */ -#if !defined(MBEDTLS_PSK_MAX_LEN) -#define MBEDTLS_PSK_MAX_LEN 32 /* 256 bits */ -#endif - -/* Dummy type used only for its size */ -union mbedtls_ssl_premaster_secret -{ -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) - unsigned char _pms_rsa[48]; /* RFC 5246 8.1.1 */ -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) - unsigned char _pms_dhm[MBEDTLS_MPI_MAX_SIZE]; /* RFC 5246 8.1.2 */ -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) - unsigned char _pms_ecdh[MBEDTLS_ECP_MAX_BYTES]; /* RFC 4492 5.10 */ -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) - unsigned char _pms_psk[4 + 2 * MBEDTLS_PSK_MAX_LEN]; /* RFC 4279 2 */ -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) - unsigned char _pms_dhe_psk[4 + MBEDTLS_MPI_MAX_SIZE - + MBEDTLS_PSK_MAX_LEN]; /* RFC 4279 3 */ -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) - unsigned char _pms_rsa_psk[52 + MBEDTLS_PSK_MAX_LEN]; /* RFC 4279 4 */ -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) - unsigned char _pms_ecdhe_psk[4 + MBEDTLS_ECP_MAX_BYTES - + MBEDTLS_PSK_MAX_LEN]; /* RFC 5489 2 */ -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - unsigned char _pms_ecjpake[32]; /* Thread spec: SHA-256 output */ -#endif -}; - -#define MBEDTLS_PREMASTER_SIZE sizeof( union mbedtls_ssl_premaster_secret ) - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * SSL state machine - */ -typedef enum -{ - MBEDTLS_SSL_HELLO_REQUEST, - MBEDTLS_SSL_CLIENT_HELLO, - MBEDTLS_SSL_SERVER_HELLO, - MBEDTLS_SSL_SERVER_CERTIFICATE, - MBEDTLS_SSL_SERVER_KEY_EXCHANGE, - MBEDTLS_SSL_CERTIFICATE_REQUEST, - MBEDTLS_SSL_SERVER_HELLO_DONE, - MBEDTLS_SSL_CLIENT_CERTIFICATE, - MBEDTLS_SSL_CLIENT_KEY_EXCHANGE, - MBEDTLS_SSL_CERTIFICATE_VERIFY, - MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC, - MBEDTLS_SSL_CLIENT_FINISHED, - MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC, - MBEDTLS_SSL_SERVER_FINISHED, - MBEDTLS_SSL_FLUSH_BUFFERS, - MBEDTLS_SSL_HANDSHAKE_WRAPUP, - MBEDTLS_SSL_HANDSHAKE_OVER, - MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET, - MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT, -} -mbedtls_ssl_states; - -/** - * \brief Callback type: send data on the network. - * - * \note That callback may be either blocking or non-blocking. - * - * \param ctx Context for the send callback (typically a file descriptor) - * \param buf Buffer holding the data to send - * \param len Length of the data to send - * - * \return The callback must return the number of bytes sent if any, - * or a non-zero error code. - * If performing non-blocking I/O, \c MBEDTLS_ERR_SSL_WANT_WRITE - * must be returned when the operation would block. - * - * \note The callback is allowed to send fewer bytes than requested. - * It must always return the number of bytes actually sent. - */ -typedef int mbedtls_ssl_send_t( void *ctx, - const unsigned char *buf, - size_t len ); - -/** - * \brief Callback type: receive data from the network. - * - * \note That callback may be either blocking or non-blocking. - * - * \param ctx Context for the receive callback (typically a file - * descriptor) - * \param buf Buffer to write the received data to - * \param len Length of the receive buffer - * - * \return The callback must return the number of bytes received, - * or a non-zero error code. - * If performing non-blocking I/O, \c MBEDTLS_ERR_SSL_WANT_READ - * must be returned when the operation would block. - * - * \note The callback may receive fewer bytes than the length of the - * buffer. It must always return the number of bytes actually - * received and written to the buffer. - */ -typedef int mbedtls_ssl_recv_t( void *ctx, - unsigned char *buf, - size_t len ); - -/** - * \brief Callback type: receive data from the network, with timeout - * - * \note That callback must block until data is received, or the - * timeout delay expires, or the operation is interrupted by a - * signal. - * - * \param ctx Context for the receive callback (typically a file descriptor) - * \param buf Buffer to write the received data to - * \param len Length of the receive buffer - * \param timeout Maximum nomber of millisecondes to wait for data - * 0 means no timeout (potentially waiting forever) - * - * \return The callback must return the number of bytes received, - * or a non-zero error code: - * \c MBEDTLS_ERR_SSL_TIMEOUT if the operation timed out, - * \c MBEDTLS_ERR_SSL_WANT_READ if interrupted by a signal. - * - * \note The callback may receive fewer bytes than the length of the - * buffer. It must always return the number of bytes actually - * received and written to the buffer. - */ -typedef int mbedtls_ssl_recv_timeout_t( void *ctx, - unsigned char *buf, - size_t len, - uint32_t timeout ); -/** - * \brief Callback type: set a pair of timers/delays to watch - * - * \param ctx Context pointer - * \param int_ms Intermediate delay in milliseconds - * \param fin_ms Final delay in milliseconds - * 0 cancels the current timer. - * - * \note This callback must at least store the necessary information - * for the associated \c mbedtls_ssl_get_timer_t callback to - * return correct information. - * - * \note If using a event-driven style of programming, an event must - * be generated when the final delay is passed. The event must - * cause a call to \c mbedtls_ssl_handshake() with the proper - * SSL context to be scheduled. Care must be taken to ensure - * that at most one such call happens at a time. - * - * \note Only one timer at a time must be running. Calling this - * function while a timer is running must cancel it. Cancelled - * timers must not generate any event. - */ -typedef void mbedtls_ssl_set_timer_t( void * ctx, - uint32_t int_ms, - uint32_t fin_ms ); - -/** - * \brief Callback type: get status of timers/delays - * - * \param ctx Context pointer - * - * \return This callback must return: - * -1 if cancelled (fin_ms == 0), - * 0 if none of the delays have passed, - * 1 if only the intermediate delay has passed, - * 2 if the final delay has passed. - */ -typedef int mbedtls_ssl_get_timer_t( void * ctx ); - -/* Defined below */ -typedef struct mbedtls_ssl_session mbedtls_ssl_session; -typedef struct mbedtls_ssl_context mbedtls_ssl_context; -typedef struct mbedtls_ssl_config mbedtls_ssl_config; - -/* Defined in ssl_internal.h */ -typedef struct mbedtls_ssl_transform mbedtls_ssl_transform; -typedef struct mbedtls_ssl_handshake_params mbedtls_ssl_handshake_params; -typedef struct mbedtls_ssl_sig_hash_set_t mbedtls_ssl_sig_hash_set_t; -#if defined(MBEDTLS_X509_CRT_PARSE_C) -typedef struct mbedtls_ssl_key_cert mbedtls_ssl_key_cert; -#endif -#if defined(MBEDTLS_SSL_PROTO_DTLS) -typedef struct mbedtls_ssl_flight_item mbedtls_ssl_flight_item; -#endif - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) -#if defined(MBEDTLS_X509_CRT_PARSE_C) -/** - * \brief Callback type: start external signature operation. - * - * This callback is called during an SSL handshake to start - * a signature decryption operation using an - * external processor. The parameter \p cert contains - * the public key; it is up to the callback function to - * determine how to access the associated private key. - * - * This function typically sends or enqueues a request, and - * does not wait for the operation to complete. This allows - * the handshake step to be non-blocking. - * - * The parameters \p ssl and \p cert are guaranteed to remain - * valid throughout the handshake. On the other hand, this - * function must save the contents of \p hash if the value - * is needed for later processing, because the \p hash buffer - * is no longer valid after this function returns. - * - * This function may call mbedtls_ssl_set_async_operation_data() - * to store an operation context for later retrieval - * by the resume or cancel callback. - * - * \note For RSA signatures, this function must produce output - * that is consistent with PKCS#1 v1.5 in the same way as - * mbedtls_rsa_pkcs1_sign(). Before the private key operation, - * apply the padding steps described in RFC 8017, section 9.2 - * "EMSA-PKCS1-v1_5" as follows. - * - If \p md_alg is #MBEDTLS_MD_NONE, apply the PKCS#1 v1.5 - * encoding, treating \p hash as the DigestInfo to be - * padded. In other words, apply EMSA-PKCS1-v1_5 starting - * from step 3, with `T = hash` and `tLen = hash_len`. - * - If `md_alg != MBEDTLS_MD_NONE`, apply the PKCS#1 v1.5 - * encoding, treating \p hash as the hash to be encoded and - * padded. In other words, apply EMSA-PKCS1-v1_5 starting - * from step 2, with `digestAlgorithm` obtained by calling - * mbedtls_oid_get_oid_by_md() on \p md_alg. - * - * \note For ECDSA signatures, the output format is the DER encoding - * `Ecdsa-Sig-Value` defined in - * [RFC 4492 section 5.4](https://tools.ietf.org/html/rfc4492#section-5.4). - * - * \param ssl The SSL connection instance. It should not be - * modified other than via - * mbedtls_ssl_set_async_operation_data(). - * \param cert Certificate containing the public key. - * In simple cases, this is one of the pointers passed to - * mbedtls_ssl_conf_own_cert() when configuring the SSL - * connection. However, if other callbacks are used, this - * property may not hold. For example, if an SNI callback - * is registered with mbedtls_ssl_conf_sni(), then - * this callback determines what certificate is used. - * \param md_alg Hash algorithm. - * \param hash Buffer containing the hash. This buffer is - * no longer valid when the function returns. - * \param hash_len Size of the \c hash buffer in bytes. - * - * \return 0 if the operation was started successfully and the SSL - * stack should call the resume callback immediately. - * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if the operation - * was started successfully and the SSL stack should return - * immediately without calling the resume callback yet. - * \return #MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH if the external - * processor does not support this key. The SSL stack will - * use the private key object instead. - * \return Any other error indicates a fatal failure and is - * propagated up the call chain. The callback should - * use \c MBEDTLS_ERR_PK_xxx error codes, and must not - * use \c MBEDTLS_ERR_SSL_xxx error codes except as - * directed in the documentation of this callback. - */ -typedef int mbedtls_ssl_async_sign_t( mbedtls_ssl_context *ssl, - mbedtls_x509_crt *cert, - mbedtls_md_type_t md_alg, - const unsigned char *hash, - size_t hash_len ); - -/** - * \brief Callback type: start external decryption operation. - * - * This callback is called during an SSL handshake to start - * an RSA decryption operation using an - * external processor. The parameter \p cert contains - * the public key; it is up to the callback function to - * determine how to access the associated private key. - * - * This function typically sends or enqueues a request, and - * does not wait for the operation to complete. This allows - * the handshake step to be non-blocking. - * - * The parameters \p ssl and \p cert are guaranteed to remain - * valid throughout the handshake. On the other hand, this - * function must save the contents of \p input if the value - * is needed for later processing, because the \p input buffer - * is no longer valid after this function returns. - * - * This function may call mbedtls_ssl_set_async_operation_data() - * to store an operation context for later retrieval - * by the resume or cancel callback. - * - * \warning RSA decryption as used in TLS is subject to a potential - * timing side channel attack first discovered by Bleichenbacher - * in 1998. This attack can be remotely exploitable - * in practice. To avoid this attack, you must ensure that - * if the callback performs an RSA decryption, the time it - * takes to execute and return the result does not depend - * on whether the RSA decryption succeeded or reported - * invalid padding. - * - * \param ssl The SSL connection instance. It should not be - * modified other than via - * mbedtls_ssl_set_async_operation_data(). - * \param cert Certificate containing the public key. - * In simple cases, this is one of the pointers passed to - * mbedtls_ssl_conf_own_cert() when configuring the SSL - * connection. However, if other callbacks are used, this - * property may not hold. For example, if an SNI callback - * is registered with mbedtls_ssl_conf_sni(), then - * this callback determines what certificate is used. - * \param input Buffer containing the input ciphertext. This buffer - * is no longer valid when the function returns. - * \param input_len Size of the \p input buffer in bytes. - * - * \return 0 if the operation was started successfully and the SSL - * stack should call the resume callback immediately. - * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if the operation - * was started successfully and the SSL stack should return - * immediately without calling the resume callback yet. - * \return #MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH if the external - * processor does not support this key. The SSL stack will - * use the private key object instead. - * \return Any other error indicates a fatal failure and is - * propagated up the call chain. The callback should - * use \c MBEDTLS_ERR_PK_xxx error codes, and must not - * use \c MBEDTLS_ERR_SSL_xxx error codes except as - * directed in the documentation of this callback. - */ -typedef int mbedtls_ssl_async_decrypt_t( mbedtls_ssl_context *ssl, - mbedtls_x509_crt *cert, - const unsigned char *input, - size_t input_len ); -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -/** - * \brief Callback type: resume external operation. - * - * This callback is called during an SSL handshake to resume - * an external operation started by the - * ::mbedtls_ssl_async_sign_t or - * ::mbedtls_ssl_async_decrypt_t callback. - * - * This function typically checks the status of a pending - * request or causes the request queue to make progress, and - * does not wait for the operation to complete. This allows - * the handshake step to be non-blocking. - * - * This function may call mbedtls_ssl_get_async_operation_data() - * to retrieve an operation context set by the start callback. - * It may call mbedtls_ssl_set_async_operation_data() to modify - * this context. - * - * Note that when this function returns a status other than - * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS, it must free any - * resources associated with the operation. - * - * \param ssl The SSL connection instance. It should not be - * modified other than via - * mbedtls_ssl_set_async_operation_data(). - * \param output Buffer containing the output (signature or decrypted - * data) on success. - * \param output_len On success, number of bytes written to \p output. - * \param output_size Size of the \p output buffer in bytes. - * - * \return 0 if output of the operation is available in the - * \p output buffer. - * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if the operation - * is still in progress. Subsequent requests for progress - * on the SSL connection will call the resume callback - * again. - * \return Any other error means that the operation is aborted. - * The SSL handshake is aborted. The callback should - * use \c MBEDTLS_ERR_PK_xxx error codes, and must not - * use \c MBEDTLS_ERR_SSL_xxx error codes except as - * directed in the documentation of this callback. - */ -typedef int mbedtls_ssl_async_resume_t( mbedtls_ssl_context *ssl, - unsigned char *output, - size_t *output_len, - size_t output_size ); - -/** - * \brief Callback type: cancel external operation. - * - * This callback is called if an SSL connection is closed - * while an asynchronous operation is in progress. Note that - * this callback is not called if the - * ::mbedtls_ssl_async_resume_t callback has run and has - * returned a value other than - * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS, since in that case - * the asynchronous operation has already completed. - * - * This function may call mbedtls_ssl_get_async_operation_data() - * to retrieve an operation context set by the start callback. - * - * \param ssl The SSL connection instance. It should not be - * modified. - */ -typedef void mbedtls_ssl_async_cancel_t( mbedtls_ssl_context *ssl ); -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) && \ - !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) -#define MBEDTLS_SSL_PEER_CERT_DIGEST_MAX_LEN 48 -#if defined(MBEDTLS_SHA256_C) -#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE MBEDTLS_MD_SHA256 -#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN 32 -#elif defined(MBEDTLS_SHA512_C) -#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE MBEDTLS_MD_SHA384 -#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN 48 -#elif defined(MBEDTLS_SHA1_C) -#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE MBEDTLS_MD_SHA1 -#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN 20 -#else -/* This is already checked in check_config.h, but be sure. */ -#error "Bad configuration - need SHA-1, SHA-256 or SHA-512 enabled to compute digest of peer CRT." -#endif -#endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED && - !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - -/* - * This structure is used for storing current session data. - */ -struct mbedtls_ssl_session -{ -#if defined(MBEDTLS_HAVE_TIME) - mbedtls_time_t start; /*!< starting time */ -#endif - int ciphersuite; /*!< chosen ciphersuite */ - int compression; /*!< chosen compression */ - size_t id_len; /*!< session id length */ - unsigned char id[32]; /*!< session identifier */ - unsigned char master[48]; /*!< the master secret */ - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - mbedtls_x509_crt *peer_cert; /*!< peer X.509 cert chain */ -#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - /*! The digest of the peer's end-CRT. This must be kept to detect CRT - * changes during renegotiation, mitigating the triple handshake attack. */ - unsigned char *peer_cert_digest; - size_t peer_cert_digest_len; - mbedtls_md_type_t peer_cert_digest_type; -#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - uint32_t verify_result; /*!< verification result */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) - unsigned char *ticket; /*!< RFC 5077 session ticket */ - size_t ticket_len; /*!< session ticket length */ - uint32_t ticket_lifetime; /*!< ticket lifetime hint */ -#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */ - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - unsigned char mfl_code; /*!< MaxFragmentLength negotiated by peer */ -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) - int trunc_hmac; /*!< flag for truncated hmac activation */ -#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - int encrypt_then_mac; /*!< flag for EtM activation */ -#endif -}; - -/** - * SSL/TLS configuration to be shared between mbedtls_ssl_context structures. - */ -struct mbedtls_ssl_config -{ - /* Group items by size (largest first) to minimize padding overhead */ - - /* - * Pointers - */ - - const int *ciphersuite_list[4]; /*!< allowed ciphersuites per version */ - - /** Callback for printing debug output */ - void (*f_dbg)(void *, int, const char *, int, const char *); - void *p_dbg; /*!< context for the debug function */ - - /** Callback for getting (pseudo-)random numbers */ - int (*f_rng)(void *, unsigned char *, size_t); - void *p_rng; /*!< context for the RNG function */ - - /** Callback to retrieve a session from the cache */ - int (*f_get_cache)(void *, mbedtls_ssl_session *); - /** Callback to store a session into the cache */ - int (*f_set_cache)(void *, const mbedtls_ssl_session *); - void *p_cache; /*!< context for cache callbacks */ - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - /** Callback for setting cert according to SNI extension */ - int (*f_sni)(void *, mbedtls_ssl_context *, const unsigned char *, size_t); - void *p_sni; /*!< context for SNI callback */ -#endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - /** Callback to customize X.509 certificate chain verification */ - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *); - void *p_vrfy; /*!< context for X.509 verify calllback */ -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) - /** Callback to retrieve PSK key from identity */ - int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *, size_t); - void *p_psk; /*!< context for PSK callback */ -#endif - -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) - /** Callback to create & write a cookie for ClientHello veirifcation */ - int (*f_cookie_write)( void *, unsigned char **, unsigned char *, - const unsigned char *, size_t ); - /** Callback to verify validity of a ClientHello cookie */ - int (*f_cookie_check)( void *, const unsigned char *, size_t, - const unsigned char *, size_t ); - void *p_cookie; /*!< context for the cookie callbacks */ -#endif - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_SRV_C) - /** Callback to create & write a session ticket */ - int (*f_ticket_write)( void *, const mbedtls_ssl_session *, - unsigned char *, const unsigned char *, size_t *, uint32_t * ); - /** Callback to parse a session ticket into a session structure */ - int (*f_ticket_parse)( void *, mbedtls_ssl_session *, unsigned char *, size_t); - void *p_ticket; /*!< context for the ticket callbacks */ -#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_SRV_C */ - -#if defined(MBEDTLS_SSL_EXPORT_KEYS) - /** Callback to export key block and master secret */ - int (*f_export_keys)( void *, const unsigned char *, - const unsigned char *, size_t, size_t, size_t ); - void *p_export_keys; /*!< context for key export callback */ -#endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - const mbedtls_x509_crt_profile *cert_profile; /*!< verification profile */ - mbedtls_ssl_key_cert *key_cert; /*!< own certificate/key pair(s) */ - mbedtls_x509_crt *ca_chain; /*!< trusted CAs */ - mbedtls_x509_crl *ca_crl; /*!< trusted CAs CRLs */ -#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) - mbedtls_x509_crt_ca_cb_t f_ca_cb; - void *p_ca_cb; -#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) -#if defined(MBEDTLS_X509_CRT_PARSE_C) - mbedtls_ssl_async_sign_t *f_async_sign_start; /*!< start asynchronous signature operation */ - mbedtls_ssl_async_decrypt_t *f_async_decrypt_start; /*!< start asynchronous decryption operation */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - mbedtls_ssl_async_resume_t *f_async_resume; /*!< resume asynchronous operation */ - mbedtls_ssl_async_cancel_t *f_async_cancel; /*!< cancel asynchronous operation */ - void *p_async_config_data; /*!< Configuration data set by mbedtls_ssl_conf_async_private_cb(). */ -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) - const int *sig_hashes; /*!< allowed signature hashes */ -#endif - -#if defined(MBEDTLS_ECP_C) - const mbedtls_ecp_group_id *curve_list; /*!< allowed curves */ -#endif - -#if defined(MBEDTLS_DHM_C) - mbedtls_mpi dhm_P; /*!< prime modulus for DHM */ - mbedtls_mpi dhm_G; /*!< generator for DHM */ -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_key_handle_t psk_opaque; /*!< PSA key slot holding opaque PSK. - * This field should only be set via - * mbedtls_ssl_conf_psk_opaque(). - * If either no PSK or a raw PSK have - * been configured, this has value \c 0. */ -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - unsigned char *psk; /*!< The raw pre-shared key. This field should - * only be set via mbedtls_ssl_conf_psk(). - * If either no PSK or an opaque PSK - * have been configured, this has value NULL. */ - size_t psk_len; /*!< The length of the raw pre-shared key. - * This field should only be set via - * mbedtls_ssl_conf_psk(). - * Its value is non-zero if and only if - * \c psk is not \c NULL. */ - - unsigned char *psk_identity; /*!< The PSK identity for PSK negotiation. - * This field should only be set via - * mbedtls_ssl_conf_psk(). - * This is set if and only if either - * \c psk or \c psk_opaque are set. */ - size_t psk_identity_len;/*!< The length of PSK identity. - * This field should only be set via - * mbedtls_ssl_conf_psk(). - * Its value is non-zero if and only if - * \c psk is not \c NULL or \c psk_opaque - * is not \c 0. */ -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ - -#if defined(MBEDTLS_SSL_ALPN) - const char **alpn_list; /*!< ordered list of protocols */ -#endif - - /* - * Numerical settings (int then char) - */ - - uint32_t read_timeout; /*!< timeout for mbedtls_ssl_read (ms) */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - uint32_t hs_timeout_min; /*!< initial value of the handshake - retransmission timeout (ms) */ - uint32_t hs_timeout_max; /*!< maximum value of the handshake - retransmission timeout (ms) */ -#endif - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - int renego_max_records; /*!< grace period for renegotiation */ - unsigned char renego_period[8]; /*!< value of the record counters - that triggers renegotiation */ -#endif - -#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) - unsigned int badmac_limit; /*!< limit of records with a bad MAC */ -#endif - -#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C) - unsigned int dhm_min_bitlen; /*!< min. bit length of the DHM prime */ -#endif - - unsigned char max_major_ver; /*!< max. major version used */ - unsigned char max_minor_ver; /*!< max. minor version used */ - unsigned char min_major_ver; /*!< min. major version used */ - unsigned char min_minor_ver; /*!< min. minor version used */ - - /* - * Flags (bitfields) - */ - - unsigned int endpoint : 1; /*!< 0: client, 1: server */ - unsigned int transport : 1; /*!< stream (TLS) or datagram (DTLS) */ - unsigned int authmode : 2; /*!< MBEDTLS_SSL_VERIFY_XXX */ - /* needed even with renego disabled for LEGACY_BREAK_HANDSHAKE */ - unsigned int allow_legacy_renegotiation : 2 ; /*!< MBEDTLS_LEGACY_XXX */ -#if defined(MBEDTLS_ARC4_C) - unsigned int arc4_disabled : 1; /*!< blacklist RC4 ciphersuites? */ -#endif -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - unsigned int mfl_code : 3; /*!< desired fragment length */ -#endif -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - unsigned int encrypt_then_mac : 1 ; /*!< negotiate encrypt-then-mac? */ -#endif -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - unsigned int extended_ms : 1; /*!< negotiate extended master secret? */ -#endif -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) - unsigned int anti_replay : 1; /*!< detect and prevent replay? */ -#endif -#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) - unsigned int cbc_record_splitting : 1; /*!< do cbc record splitting */ -#endif -#if defined(MBEDTLS_SSL_RENEGOTIATION) - unsigned int disable_renegotiation : 1; /*!< disable renegotiation? */ -#endif -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) - unsigned int trunc_hmac : 1; /*!< negotiate truncated hmac? */ -#endif -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - unsigned int session_tickets : 1; /*!< use session tickets? */ -#endif -#if defined(MBEDTLS_SSL_FALLBACK_SCSV) && defined(MBEDTLS_SSL_CLI_C) - unsigned int fallback : 1; /*!< is this a fallback? */ -#endif -#if defined(MBEDTLS_SSL_SRV_C) - unsigned int cert_req_ca_list : 1; /*!< enable sending CA list in - Certificate Request messages? */ -#endif -}; - - -struct mbedtls_ssl_context -{ - const mbedtls_ssl_config *conf; /*!< configuration information */ - - /* - * Miscellaneous - */ - int state; /*!< SSL handshake: current state */ -#if defined(MBEDTLS_SSL_RENEGOTIATION) - int renego_status; /*!< Initial, in progress, pending? */ - int renego_records_seen; /*!< Records since renego request, or with DTLS, - number of retransmissions of request if - renego_max_records is < 0 */ -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - - int major_ver; /*!< equal to MBEDTLS_SSL_MAJOR_VERSION_3 */ - int minor_ver; /*!< either 0 (SSL3) or 1 (TLS1.0) */ - -#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) - unsigned badmac_seen; /*!< records with a bad MAC received */ -#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */ - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - /** Callback to customize X.509 certificate chain verification */ - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *); - void *p_vrfy; /*!< context for X.509 verify callback */ -#endif - - mbedtls_ssl_send_t *f_send; /*!< Callback for network send */ - mbedtls_ssl_recv_t *f_recv; /*!< Callback for network receive */ - mbedtls_ssl_recv_timeout_t *f_recv_timeout; - /*!< Callback for network receive with timeout */ - - void *p_bio; /*!< context for I/O operations */ - - /* - * Session layer - */ - mbedtls_ssl_session *session_in; /*!< current session data (in) */ - mbedtls_ssl_session *session_out; /*!< current session data (out) */ - mbedtls_ssl_session *session; /*!< negotiated session data */ - mbedtls_ssl_session *session_negotiate; /*!< session data in negotiation */ - - mbedtls_ssl_handshake_params *handshake; /*!< params required only during - the handshake process */ - - /* - * Record layer transformations - */ - mbedtls_ssl_transform *transform_in; /*!< current transform params (in) */ - mbedtls_ssl_transform *transform_out; /*!< current transform params (in) */ - mbedtls_ssl_transform *transform; /*!< negotiated transform params */ - mbedtls_ssl_transform *transform_negotiate; /*!< transform params in negotiation */ - - /* - * Timers - */ - void *p_timer; /*!< context for the timer callbacks */ - - mbedtls_ssl_set_timer_t *f_set_timer; /*!< set timer callback */ - mbedtls_ssl_get_timer_t *f_get_timer; /*!< get timer callback */ - - /* - * Record layer (incoming data) - */ - unsigned char *in_buf; /*!< input buffer */ - unsigned char *in_ctr; /*!< 64-bit incoming message counter - TLS: maintained by us - DTLS: read from peer */ - unsigned char *in_hdr; /*!< start of record header */ - unsigned char *in_len; /*!< two-bytes message length field */ - unsigned char *in_iv; /*!< ivlen-byte IV */ - unsigned char *in_msg; /*!< message contents (in_iv+ivlen) */ - unsigned char *in_offt; /*!< read offset in application data */ - - int in_msgtype; /*!< record header: message type */ - size_t in_msglen; /*!< record header: message length */ - size_t in_left; /*!< amount of data read so far */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - uint16_t in_epoch; /*!< DTLS epoch for incoming records */ - size_t next_record_offset; /*!< offset of the next record in datagram - (equal to in_left if none) */ -#endif /* MBEDTLS_SSL_PROTO_DTLS */ -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) - uint64_t in_window_top; /*!< last validated record seq_num */ - uint64_t in_window; /*!< bitmask for replay detection */ -#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ - - size_t in_hslen; /*!< current handshake message length, - including the handshake header */ - int nb_zero; /*!< # of 0-length encrypted messages */ - - int keep_current_message; /*!< drop or reuse current message - on next call to record layer? */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - uint8_t disable_datagram_packing; /*!< Disable packing multiple records - * within a single datagram. */ -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - /* - * Record layer (outgoing data) - */ - unsigned char *out_buf; /*!< output buffer */ - unsigned char *out_ctr; /*!< 64-bit outgoing message counter */ - unsigned char *out_hdr; /*!< start of record header */ - unsigned char *out_len; /*!< two-bytes message length field */ - unsigned char *out_iv; /*!< ivlen-byte IV */ - unsigned char *out_msg; /*!< message contents (out_iv+ivlen) */ - - int out_msgtype; /*!< record header: message type */ - size_t out_msglen; /*!< record header: message length */ - size_t out_left; /*!< amount of data not yet written */ - - unsigned char cur_out_ctr[8]; /*!< Outgoing record sequence number. */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - uint16_t mtu; /*!< path mtu, used to fragment outgoing messages */ -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -#if defined(MBEDTLS_ZLIB_SUPPORT) - unsigned char *compress_buf; /*!< zlib data buffer */ -#endif /* MBEDTLS_ZLIB_SUPPORT */ -#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) - signed char split_done; /*!< current record already splitted? */ -#endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */ - - /* - * PKI layer - */ - int client_auth; /*!< flag for client auth. */ - - /* - * User settings - */ -#if defined(MBEDTLS_X509_CRT_PARSE_C) - char *hostname; /*!< expected peer CN for verification - (and SNI if available) */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_SSL_ALPN) - const char *alpn_chosen; /*!< negotiated protocol */ -#endif /* MBEDTLS_SSL_ALPN */ - - /* - * Information for DTLS hello verify - */ -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) - unsigned char *cli_id; /*!< transport-level ID of the client */ - size_t cli_id_len; /*!< length of cli_id */ -#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */ - - /* - * Secure renegotiation - */ - /* needed to know when to send extension on server */ - int secure_renegotiation; /*!< does peer support legacy or - secure renegotiation */ -#if defined(MBEDTLS_SSL_RENEGOTIATION) - size_t verify_data_len; /*!< length of verify data stored */ - char own_verify_data[MBEDTLS_SSL_VERIFY_DATA_MAX_LEN]; /*!< previous handshake verify data */ - char peer_verify_data[MBEDTLS_SSL_VERIFY_DATA_MAX_LEN]; /*!< previous handshake verify data */ -#endif /* MBEDTLS_SSL_RENEGOTIATION */ -}; - -#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) - -#define MBEDTLS_SSL_CHANNEL_OUTBOUND 0 -#define MBEDTLS_SSL_CHANNEL_INBOUND 1 - -extern int (*mbedtls_ssl_hw_record_init)(mbedtls_ssl_context *ssl, - const unsigned char *key_enc, const unsigned char *key_dec, - size_t keylen, - const unsigned char *iv_enc, const unsigned char *iv_dec, - size_t ivlen, - const unsigned char *mac_enc, const unsigned char *mac_dec, - size_t maclen); -extern int (*mbedtls_ssl_hw_record_activate)(mbedtls_ssl_context *ssl, int direction); -extern int (*mbedtls_ssl_hw_record_reset)(mbedtls_ssl_context *ssl); -extern int (*mbedtls_ssl_hw_record_write)(mbedtls_ssl_context *ssl); -extern int (*mbedtls_ssl_hw_record_read)(mbedtls_ssl_context *ssl); -extern int (*mbedtls_ssl_hw_record_finish)(mbedtls_ssl_context *ssl); -#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ - -/** - * \brief Return the name of the ciphersuite associated with the - * given ID - * - * \param ciphersuite_id SSL ciphersuite ID - * - * \return a string containing the ciphersuite name - */ -const char *mbedtls_ssl_get_ciphersuite_name( const int ciphersuite_id ); - -/** - * \brief Return the ID of the ciphersuite associated with the - * given name - * - * \param ciphersuite_name SSL ciphersuite name - * - * \return the ID with the ciphersuite or 0 if not found - */ -int mbedtls_ssl_get_ciphersuite_id( const char *ciphersuite_name ); - -/** - * \brief Initialize an SSL context - * Just makes the context ready for mbedtls_ssl_setup() or - * mbedtls_ssl_free() - * - * \param ssl SSL context - */ -void mbedtls_ssl_init( mbedtls_ssl_context *ssl ); - -/** - * \brief Set up an SSL context for use - * - * \note No copy of the configuration context is made, it can be - * shared by many mbedtls_ssl_context structures. - * - * \warning The conf structure will be accessed during the session. - * It must not be modified or freed as long as the session - * is active. - * - * \warning This function must be called exactly once per context. - * Calling mbedtls_ssl_setup again is not supported, even - * if no session is active. - * - * \param ssl SSL context - * \param conf SSL configuration to use - * - * \return 0 if successful, or MBEDTLS_ERR_SSL_ALLOC_FAILED if - * memory allocation failed - */ -int mbedtls_ssl_setup( mbedtls_ssl_context *ssl, - const mbedtls_ssl_config *conf ); - -/** - * \brief Reset an already initialized SSL context for re-use - * while retaining application-set variables, function - * pointers and data. - * - * \param ssl SSL context - * \return 0 if successful, or MBEDTLS_ERR_SSL_ALLOC_FAILED, - MBEDTLS_ERR_SSL_HW_ACCEL_FAILED or - * MBEDTLS_ERR_SSL_COMPRESSION_FAILED - */ -int mbedtls_ssl_session_reset( mbedtls_ssl_context *ssl ); - -/** - * \brief Set the current endpoint type - * - * \param conf SSL configuration - * \param endpoint must be MBEDTLS_SSL_IS_CLIENT or MBEDTLS_SSL_IS_SERVER - */ -void mbedtls_ssl_conf_endpoint( mbedtls_ssl_config *conf, int endpoint ); - -/** - * \brief Set the transport type (TLS or DTLS). - * Default: TLS - * - * \note For DTLS, you must either provide a recv callback that - * doesn't block, or one that handles timeouts, see - * \c mbedtls_ssl_set_bio(). You also need to provide timer - * callbacks with \c mbedtls_ssl_set_timer_cb(). - * - * \param conf SSL configuration - * \param transport transport type: - * MBEDTLS_SSL_TRANSPORT_STREAM for TLS, - * MBEDTLS_SSL_TRANSPORT_DATAGRAM for DTLS. - */ -void mbedtls_ssl_conf_transport( mbedtls_ssl_config *conf, int transport ); - -/** - * \brief Set the certificate verification mode - * Default: NONE on server, REQUIRED on client - * - * \param conf SSL configuration - * \param authmode can be: - * - * MBEDTLS_SSL_VERIFY_NONE: peer certificate is not checked - * (default on server) - * (insecure on client) - * - * MBEDTLS_SSL_VERIFY_OPTIONAL: peer certificate is checked, however the - * handshake continues even if verification failed; - * mbedtls_ssl_get_verify_result() can be called after the - * handshake is complete. - * - * MBEDTLS_SSL_VERIFY_REQUIRED: peer *must* present a valid certificate, - * handshake is aborted if verification failed. - * (default on client) - * - * \note On client, MBEDTLS_SSL_VERIFY_REQUIRED is the recommended mode. - * With MBEDTLS_SSL_VERIFY_OPTIONAL, the user needs to call mbedtls_ssl_get_verify_result() at - * the right time(s), which may not be obvious, while REQUIRED always perform - * the verification as soon as possible. For example, REQUIRED was protecting - * against the "triple handshake" attack even before it was found. - */ -void mbedtls_ssl_conf_authmode( mbedtls_ssl_config *conf, int authmode ); - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -/** - * \brief Set the verification callback (Optional). - * - * If set, the provided verify callback is called for each - * certificate in the peer's CRT chain, including the trusted - * root. For more information, please see the documentation of - * \c mbedtls_x509_crt_verify(). - * - * \note For per context callbacks and contexts, please use - * mbedtls_ssl_set_verify() instead. - * - * \param conf The SSL configuration to use. - * \param f_vrfy The verification callback to use during CRT verification. - * \param p_vrfy The opaque context to be passed to the callback. - */ -void mbedtls_ssl_conf_verify( mbedtls_ssl_config *conf, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy ); -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -/** - * \brief Set the random number generator callback - * - * \param conf SSL configuration - * \param f_rng RNG function - * \param p_rng RNG parameter - */ -void mbedtls_ssl_conf_rng( mbedtls_ssl_config *conf, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); - -/** - * \brief Set the debug callback - * - * The callback has the following argument: - * void * opaque context for the callback - * int debug level - * const char * file name - * int line number - * const char * message - * - * \param conf SSL configuration - * \param f_dbg debug function - * \param p_dbg debug parameter - */ -void mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf, - void (*f_dbg)(void *, int, const char *, int, const char *), - void *p_dbg ); - -/** - * \brief Set the underlying BIO callbacks for write, read and - * read-with-timeout. - * - * \param ssl SSL context - * \param p_bio parameter (context) shared by BIO callbacks - * \param f_send write callback - * \param f_recv read callback - * \param f_recv_timeout blocking read callback with timeout. - * - * \note One of f_recv or f_recv_timeout can be NULL, in which case - * the other is used. If both are non-NULL, f_recv_timeout is - * used and f_recv is ignored (as if it were NULL). - * - * \note The two most common use cases are: - * - non-blocking I/O, f_recv != NULL, f_recv_timeout == NULL - * - blocking I/O, f_recv == NULL, f_recv_timout != NULL - * - * \note For DTLS, you need to provide either a non-NULL - * f_recv_timeout callback, or a f_recv that doesn't block. - * - * \note See the documentations of \c mbedtls_ssl_sent_t, - * \c mbedtls_ssl_recv_t and \c mbedtls_ssl_recv_timeout_t for - * the conventions those callbacks must follow. - * - * \note On some platforms, net_sockets.c provides - * \c mbedtls_net_send(), \c mbedtls_net_recv() and - * \c mbedtls_net_recv_timeout() that are suitable to be used - * here. - */ -void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl, - void *p_bio, - mbedtls_ssl_send_t *f_send, - mbedtls_ssl_recv_t *f_recv, - mbedtls_ssl_recv_timeout_t *f_recv_timeout ); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) -/** - * \brief Set the Maximum Tranport Unit (MTU). - * Special value: 0 means unset (no limit). - * This represents the maximum size of a datagram payload - * handled by the transport layer (usually UDP) as determined - * by the network link and stack. In practice, this controls - * the maximum size datagram the DTLS layer will pass to the - * \c f_send() callback set using \c mbedtls_ssl_set_bio(). - * - * \note The limit on datagram size is converted to a limit on - * record payload by subtracting the current overhead of - * encapsulation and encryption/authentication if any. - * - * \note This can be called at any point during the connection, for - * example when a Path Maximum Transfer Unit (PMTU) - * estimate becomes available from other sources, - * such as lower (or higher) protocol layers. - * - * \note This setting only controls the size of the packets we send, - * and does not restrict the size of the datagrams we're - * willing to receive. Client-side, you can request the - * server to use smaller records with \c - * mbedtls_ssl_conf_max_frag_len(). - * - * \note If both a MTU and a maximum fragment length have been - * configured (or negotiated with the peer), the resulting - * lower limit on record payload (see first note) is used. - * - * \note This can only be used to decrease the maximum size - * of datagrams (hence records, see first note) sent. It - * cannot be used to increase the maximum size of records over - * the limit set by #MBEDTLS_SSL_OUT_CONTENT_LEN. - * - * \note Values lower than the current record layer expansion will - * result in an error when trying to send data. - * - * \note Using record compression together with a non-zero MTU value - * will result in an error when trying to send data. - * - * \param ssl SSL context - * \param mtu Value of the path MTU in bytes - */ -void mbedtls_ssl_set_mtu( mbedtls_ssl_context *ssl, uint16_t mtu ); -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -/** - * \brief Set a connection-specific verification callback (optional). - * - * If set, the provided verify callback is called for each - * certificate in the peer's CRT chain, including the trusted - * root. For more information, please see the documentation of - * \c mbedtls_x509_crt_verify(). - * - * \note This call is analogous to mbedtls_ssl_conf_verify() but - * binds the verification callback and context to an SSL context - * as opposed to an SSL configuration. - * If mbedtls_ssl_conf_verify() and mbedtls_ssl_set_verify() - * are both used, mbedtls_ssl_set_verify() takes precedence. - * - * \param ssl The SSL context to use. - * \param f_vrfy The verification callback to use during CRT verification. - * \param p_vrfy The opaque context to be passed to the callback. - */ -void mbedtls_ssl_set_verify( mbedtls_ssl_context *ssl, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy ); -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -/** - * \brief Set the timeout period for mbedtls_ssl_read() - * (Default: no timeout.) - * - * \param conf SSL configuration context - * \param timeout Timeout value in milliseconds. - * Use 0 for no timeout (default). - * - * \note With blocking I/O, this will only work if a non-NULL - * \c f_recv_timeout was set with \c mbedtls_ssl_set_bio(). - * With non-blocking I/O, this will only work if timer - * callbacks were set with \c mbedtls_ssl_set_timer_cb(). - * - * \note With non-blocking I/O, you may also skip this function - * altogether and handle timeouts at the application layer. - */ -void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout ); - -/** - * \brief Set the timer callbacks (Mandatory for DTLS.) - * - * \param ssl SSL context - * \param p_timer parameter (context) shared by timer callbacks - * \param f_set_timer set timer callback - * \param f_get_timer get timer callback. Must return: - * - * \note See the documentation of \c mbedtls_ssl_set_timer_t and - * \c mbedtls_ssl_get_timer_t for the conventions this pair of - * callbacks must follow. - * - * \note On some platforms, timing.c provides - * \c mbedtls_timing_set_delay() and - * \c mbedtls_timing_get_delay() that are suitable for using - * here, except if using an event-driven style. - * - * \note See also the "DTLS tutorial" article in our knowledge base. - * https://tls.mbed.org/kb/how-to/dtls-tutorial - */ -void mbedtls_ssl_set_timer_cb( mbedtls_ssl_context *ssl, - void *p_timer, - mbedtls_ssl_set_timer_t *f_set_timer, - mbedtls_ssl_get_timer_t *f_get_timer ); - -/** - * \brief Callback type: generate and write session ticket - * - * \note This describes what a callback implementation should do. - * This callback should generate an encrypted and - * authenticated ticket for the session and write it to the - * output buffer. Here, ticket means the opaque ticket part - * of the NewSessionTicket structure of RFC 5077. - * - * \param p_ticket Context for the callback - * \param session SSL session to be written in the ticket - * \param start Start of the output buffer - * \param end End of the output buffer - * \param tlen On exit, holds the length written - * \param lifetime On exit, holds the lifetime of the ticket in seconds - * - * \return 0 if successful, or - * a specific MBEDTLS_ERR_XXX code. - */ -typedef int mbedtls_ssl_ticket_write_t( void *p_ticket, - const mbedtls_ssl_session *session, - unsigned char *start, - const unsigned char *end, - size_t *tlen, - uint32_t *lifetime ); - -#if defined(MBEDTLS_SSL_EXPORT_KEYS) -/** - * \brief Callback type: Export key block and master secret - * - * \note This is required for certain uses of TLS, e.g. EAP-TLS - * (RFC 5216) and Thread. The key pointers are ephemeral and - * therefore must not be stored. The master secret and keys - * should not be used directly except as an input to a key - * derivation function. - * - * \param p_expkey Context for the callback - * \param ms Pointer to master secret (fixed length: 48 bytes) - * \param kb Pointer to key block, see RFC 5246 section 6.3 - * (variable length: 2 * maclen + 2 * keylen + 2 * ivlen). - * \param maclen MAC length - * \param keylen Key length - * \param ivlen IV length - * - * \return 0 if successful, or - * a specific MBEDTLS_ERR_XXX code. - */ -typedef int mbedtls_ssl_export_keys_t( void *p_expkey, - const unsigned char *ms, - const unsigned char *kb, - size_t maclen, - size_t keylen, - size_t ivlen ); -#endif /* MBEDTLS_SSL_EXPORT_KEYS */ - -/** - * \brief Callback type: parse and load session ticket - * - * \note This describes what a callback implementation should do. - * This callback should parse a session ticket as generated - * by the corresponding mbedtls_ssl_ticket_write_t function, - * and, if the ticket is authentic and valid, load the - * session. - * - * \note The implementation is allowed to modify the first len - * bytes of the input buffer, eg to use it as a temporary - * area for the decrypted ticket contents. - * - * \param p_ticket Context for the callback - * \param session SSL session to be loaded - * \param buf Start of the buffer containing the ticket - * \param len Length of the ticket. - * - * \return 0 if successful, or - * MBEDTLS_ERR_SSL_INVALID_MAC if not authentic, or - * MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED if expired, or - * any other non-zero code for other failures. - */ -typedef int mbedtls_ssl_ticket_parse_t( void *p_ticket, - mbedtls_ssl_session *session, - unsigned char *buf, - size_t len ); - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_SRV_C) -/** - * \brief Configure SSL session ticket callbacks (server only). - * (Default: none.) - * - * \note On server, session tickets are enabled by providing - * non-NULL callbacks. - * - * \note On client, use \c mbedtls_ssl_conf_session_tickets(). - * - * \param conf SSL configuration context - * \param f_ticket_write Callback for writing a ticket - * \param f_ticket_parse Callback for parsing a ticket - * \param p_ticket Context shared by the two callbacks - */ -void mbedtls_ssl_conf_session_tickets_cb( mbedtls_ssl_config *conf, - mbedtls_ssl_ticket_write_t *f_ticket_write, - mbedtls_ssl_ticket_parse_t *f_ticket_parse, - void *p_ticket ); -#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_SRV_C */ - -#if defined(MBEDTLS_SSL_EXPORT_KEYS) -/** - * \brief Configure key export callback. - * (Default: none.) - * - * \note See \c mbedtls_ssl_export_keys_t. - * - * \param conf SSL configuration context - * \param f_export_keys Callback for exporting keys - * \param p_export_keys Context for the callback - */ -void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf, - mbedtls_ssl_export_keys_t *f_export_keys, - void *p_export_keys ); -#endif /* MBEDTLS_SSL_EXPORT_KEYS */ - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) -/** - * \brief Configure asynchronous private key operation callbacks. - * - * \param conf SSL configuration context - * \param f_async_sign Callback to start a signature operation. See - * the description of ::mbedtls_ssl_async_sign_t - * for more information. This may be \c NULL if the - * external processor does not support any signature - * operation; in this case the private key object - * associated with the certificate will be used. - * \param f_async_decrypt Callback to start a decryption operation. See - * the description of ::mbedtls_ssl_async_decrypt_t - * for more information. This may be \c NULL if the - * external processor does not support any decryption - * operation; in this case the private key object - * associated with the certificate will be used. - * \param f_async_resume Callback to resume an asynchronous operation. See - * the description of ::mbedtls_ssl_async_resume_t - * for more information. This may not be \c NULL unless - * \p f_async_sign and \p f_async_decrypt are both - * \c NULL. - * \param f_async_cancel Callback to cancel an asynchronous operation. See - * the description of ::mbedtls_ssl_async_cancel_t - * for more information. This may be \c NULL if - * no cleanup is needed. - * \param config_data A pointer to configuration data which can be - * retrieved with - * mbedtls_ssl_conf_get_async_config_data(). The - * library stores this value without dereferencing it. - */ -void mbedtls_ssl_conf_async_private_cb( mbedtls_ssl_config *conf, - mbedtls_ssl_async_sign_t *f_async_sign, - mbedtls_ssl_async_decrypt_t *f_async_decrypt, - mbedtls_ssl_async_resume_t *f_async_resume, - mbedtls_ssl_async_cancel_t *f_async_cancel, - void *config_data ); - -/** - * \brief Retrieve the configuration data set by - * mbedtls_ssl_conf_async_private_cb(). - * - * \param conf SSL configuration context - * \return The configuration data set by - * mbedtls_ssl_conf_async_private_cb(). - */ -void *mbedtls_ssl_conf_get_async_config_data( const mbedtls_ssl_config *conf ); - -/** - * \brief Retrieve the asynchronous operation user context. - * - * \note This function may only be called while a handshake - * is in progress. - * - * \param ssl The SSL context to access. - * - * \return The asynchronous operation user context that was last - * set during the current handshake. If - * mbedtls_ssl_set_async_operation_data() has not yet been - * called during the current handshake, this function returns - * \c NULL. - */ -void *mbedtls_ssl_get_async_operation_data( const mbedtls_ssl_context *ssl ); - -/** - * \brief Retrieve the asynchronous operation user context. - * - * \note This function may only be called while a handshake - * is in progress. - * - * \param ssl The SSL context to access. - * \param ctx The new value of the asynchronous operation user context. - * Call mbedtls_ssl_get_async_operation_data() later during the - * same handshake to retrieve this value. - */ -void mbedtls_ssl_set_async_operation_data( mbedtls_ssl_context *ssl, - void *ctx ); -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - -/** - * \brief Callback type: generate a cookie - * - * \param ctx Context for the callback - * \param p Buffer to write to, - * must be updated to point right after the cookie - * \param end Pointer to one past the end of the output buffer - * \param info Client ID info that was passed to - * \c mbedtls_ssl_set_client_transport_id() - * \param ilen Length of info in bytes - * - * \return The callback must return 0 on success, - * or a negative error code. - */ -typedef int mbedtls_ssl_cookie_write_t( void *ctx, - unsigned char **p, unsigned char *end, - const unsigned char *info, size_t ilen ); - -/** - * \brief Callback type: verify a cookie - * - * \param ctx Context for the callback - * \param cookie Cookie to verify - * \param clen Length of cookie - * \param info Client ID info that was passed to - * \c mbedtls_ssl_set_client_transport_id() - * \param ilen Length of info in bytes - * - * \return The callback must return 0 if cookie is valid, - * or a negative error code. - */ -typedef int mbedtls_ssl_cookie_check_t( void *ctx, - const unsigned char *cookie, size_t clen, - const unsigned char *info, size_t ilen ); - -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) -/** - * \brief Register callbacks for DTLS cookies - * (Server only. DTLS only.) - * - * Default: dummy callbacks that fail, in order to force you to - * register working callbacks (and initialize their context). - * - * To disable HelloVerifyRequest, register NULL callbacks. - * - * \warning Disabling hello verification allows your server to be used - * for amplification in DoS attacks against other hosts. - * Only disable if you known this can't happen in your - * particular environment. - * - * \note See comments on \c mbedtls_ssl_handshake() about handling - * the MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED that is expected - * on the first handshake attempt when this is enabled. - * - * \note This is also necessary to handle client reconnection from - * the same port as described in RFC 6347 section 4.2.8 (only - * the variant with cookies is supported currently). See - * comments on \c mbedtls_ssl_read() for details. - * - * \param conf SSL configuration - * \param f_cookie_write Cookie write callback - * \param f_cookie_check Cookie check callback - * \param p_cookie Context for both callbacks - */ -void mbedtls_ssl_conf_dtls_cookies( mbedtls_ssl_config *conf, - mbedtls_ssl_cookie_write_t *f_cookie_write, - mbedtls_ssl_cookie_check_t *f_cookie_check, - void *p_cookie ); - -/** - * \brief Set client's transport-level identification info. - * (Server only. DTLS only.) - * - * This is usually the IP address (and port), but could be - * anything identify the client depending on the underlying - * network stack. Used for HelloVerifyRequest with DTLS. - * This is *not* used to route the actual packets. - * - * \param ssl SSL context - * \param info Transport-level info identifying the client (eg IP + port) - * \param ilen Length of info in bytes - * - * \note An internal copy is made, so the info buffer can be reused. - * - * \return 0 on success, - * MBEDTLS_ERR_SSL_BAD_INPUT_DATA if used on client, - * MBEDTLS_ERR_SSL_ALLOC_FAILED if out of memory. - */ -int mbedtls_ssl_set_client_transport_id( mbedtls_ssl_context *ssl, - const unsigned char *info, - size_t ilen ); - -#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */ - -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) -/** - * \brief Enable or disable anti-replay protection for DTLS. - * (DTLS only, no effect on TLS.) - * Default: enabled. - * - * \param conf SSL configuration - * \param mode MBEDTLS_SSL_ANTI_REPLAY_ENABLED or MBEDTLS_SSL_ANTI_REPLAY_DISABLED. - * - * \warning Disabling this is a security risk unless the application - * protocol handles duplicated packets in a safe way. You - * should not disable this without careful consideration. - * However, if your application already detects duplicated - * packets and needs information about them to adjust its - * transmission strategy, then you'll want to disable this. - */ -void mbedtls_ssl_conf_dtls_anti_replay( mbedtls_ssl_config *conf, char mode ); -#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ - -#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) -/** - * \brief Set a limit on the number of records with a bad MAC - * before terminating the connection. - * (DTLS only, no effect on TLS.) - * Default: 0 (disabled). - * - * \param conf SSL configuration - * \param limit Limit, or 0 to disable. - * - * \note If the limit is N, then the connection is terminated when - * the Nth non-authentic record is seen. - * - * \note Records with an invalid header are not counted, only the - * ones going through the authentication-decryption phase. - * - * \note This is a security trade-off related to the fact that it's - * often relatively easy for an active attacker ot inject UDP - * datagrams. On one hand, setting a low limit here makes it - * easier for such an attacker to forcibly terminated a - * connection. On the other hand, a high limit or no limit - * might make us waste resources checking authentication on - * many bogus packets. - */ -void mbedtls_ssl_conf_dtls_badmac_limit( mbedtls_ssl_config *conf, unsigned limit ); -#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - -/** - * \brief Allow or disallow packing of multiple handshake records - * within a single datagram. - * - * \param ssl The SSL context to configure. - * \param allow_packing This determines whether datagram packing may - * be used or not. A value of \c 0 means that every - * record will be sent in a separate datagram; a - * value of \c 1 means that, if space permits, - * multiple handshake messages (including CCS) belonging to - * a single flight may be packed within a single datagram. - * - * \note This is enabled by default and should only be disabled - * for test purposes, or if datagram packing causes - * interoperability issues with peers that don't support it. - * - * \note Allowing datagram packing reduces the network load since - * there's less overhead if multiple messages share the same - * datagram. Also, it increases the handshake efficiency - * since messages belonging to a single datagram will not - * be reordered in transit, and so future message buffering - * or flight retransmission (if no buffering is used) as - * means to deal with reordering are needed less frequently. - * - * \note Application records are not affected by this option and - * are currently always sent in separate datagrams. - * - */ -void mbedtls_ssl_set_datagram_packing( mbedtls_ssl_context *ssl, - unsigned allow_packing ); - -/** - * \brief Set retransmit timeout values for the DTLS handshake. - * (DTLS only, no effect on TLS.) - * - * \param conf SSL configuration - * \param min Initial timeout value in milliseconds. - * Default: 1000 (1 second). - * \param max Maximum timeout value in milliseconds. - * Default: 60000 (60 seconds). - * - * \note Default values are from RFC 6347 section 4.2.4.1. - * - * \note The 'min' value should typically be slightly above the - * expected round-trip time to your peer, plus whatever time - * it takes for the peer to process the message. For example, - * if your RTT is about 600ms and you peer needs up to 1s to - * do the cryptographic operations in the handshake, then you - * should set 'min' slightly above 1600. Lower values of 'min' - * might cause spurious resends which waste network resources, - * while larger value of 'min' will increase overall latency - * on unreliable network links. - * - * \note The more unreliable your network connection is, the larger - * your max / min ratio needs to be in order to achieve - * reliable handshakes. - * - * \note Messages are retransmitted up to log2(ceil(max/min)) times. - * For example, if min = 1s and max = 5s, the retransmit plan - * goes: send ... 1s -> resend ... 2s -> resend ... 4s -> - * resend ... 5s -> give up and return a timeout error. - */ -void mbedtls_ssl_conf_handshake_timeout( mbedtls_ssl_config *conf, uint32_t min, uint32_t max ); -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -#if defined(MBEDTLS_SSL_SRV_C) -/** - * \brief Set the session cache callbacks (server-side only) - * If not set, no session resuming is done (except if session - * tickets are enabled too). - * - * The session cache has the responsibility to check for stale - * entries based on timeout. See RFC 5246 for recommendations. - * - * Warning: session.peer_cert is cleared by the SSL/TLS layer on - * connection shutdown, so do not cache the pointer! Either set - * it to NULL or make a full copy of the certificate. - * - * The get callback is called once during the initial handshake - * to enable session resuming. The get function has the - * following parameters: (void *parameter, mbedtls_ssl_session *session) - * If a valid entry is found, it should fill the master of - * the session object with the cached values and return 0, - * return 1 otherwise. Optionally peer_cert can be set as well - * if it is properly present in cache entry. - * - * The set callback is called once during the initial handshake - * to enable session resuming after the entire handshake has - * been finished. The set function has the following parameters: - * (void *parameter, const mbedtls_ssl_session *session). The function - * should create a cache entry for future retrieval based on - * the data in the session structure and should keep in mind - * that the mbedtls_ssl_session object presented (and all its referenced - * data) is cleared by the SSL/TLS layer when the connection is - * terminated. It is recommended to add metadata to determine if - * an entry is still valid in the future. Return 0 if - * successfully cached, return 1 otherwise. - * - * \param conf SSL configuration - * \param p_cache parmater (context) for both callbacks - * \param f_get_cache session get callback - * \param f_set_cache session set callback - */ -void mbedtls_ssl_conf_session_cache( mbedtls_ssl_config *conf, - void *p_cache, - int (*f_get_cache)(void *, mbedtls_ssl_session *), - int (*f_set_cache)(void *, const mbedtls_ssl_session *) ); -#endif /* MBEDTLS_SSL_SRV_C */ - -#if defined(MBEDTLS_SSL_CLI_C) -/** - * \brief Request resumption of session (client-side only) - * Session data is copied from presented session structure. - * - * \param ssl SSL context - * \param session session context - * - * \return 0 if successful, - * MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed, - * MBEDTLS_ERR_SSL_BAD_INPUT_DATA if used server-side or - * arguments are otherwise invalid - * - * \sa mbedtls_ssl_get_session() - */ -int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session *session ); -#endif /* MBEDTLS_SSL_CLI_C */ - -/** - * \brief Set the list of allowed ciphersuites and the preference - * order. First in the list has the highest preference. - * (Overrides all version-specific lists) - * - * The ciphersuites array is not copied, and must remain - * valid for the lifetime of the ssl_config. - * - * Note: The server uses its own preferences - * over the preference of the client unless - * MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE is defined! - * - * \param conf SSL configuration - * \param ciphersuites 0-terminated list of allowed ciphersuites - */ -void mbedtls_ssl_conf_ciphersuites( mbedtls_ssl_config *conf, - const int *ciphersuites ); - -/** - * \brief Set the list of allowed ciphersuites and the - * preference order for a specific version of the protocol. - * (Only useful on the server side) - * - * The ciphersuites array is not copied, and must remain - * valid for the lifetime of the ssl_config. - * - * \param conf SSL configuration - * \param ciphersuites 0-terminated list of allowed ciphersuites - * \param major Major version number (only MBEDTLS_SSL_MAJOR_VERSION_3 - * supported) - * \param minor Minor version number (MBEDTLS_SSL_MINOR_VERSION_0, - * MBEDTLS_SSL_MINOR_VERSION_1 and MBEDTLS_SSL_MINOR_VERSION_2, - * MBEDTLS_SSL_MINOR_VERSION_3 supported) - * - * \note With DTLS, use MBEDTLS_SSL_MINOR_VERSION_2 for DTLS 1.0 - * and MBEDTLS_SSL_MINOR_VERSION_3 for DTLS 1.2 - */ -void mbedtls_ssl_conf_ciphersuites_for_version( mbedtls_ssl_config *conf, - const int *ciphersuites, - int major, int minor ); - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -/** - * \brief Set the X.509 security profile used for verification - * - * \note The restrictions are enforced for all certificates in the - * chain. However, signatures in the handshake are not covered - * by this setting but by \b mbedtls_ssl_conf_sig_hashes(). - * - * \param conf SSL configuration - * \param profile Profile to use - */ -void mbedtls_ssl_conf_cert_profile( mbedtls_ssl_config *conf, - const mbedtls_x509_crt_profile *profile ); - -/** - * \brief Set the data required to verify peer certificate - * - * \note See \c mbedtls_x509_crt_verify() for notes regarding the - * parameters ca_chain (maps to trust_ca for that function) - * and ca_crl. - * - * \param conf SSL configuration - * \param ca_chain trusted CA chain (meaning all fully trusted top-level CAs) - * \param ca_crl trusted CA CRLs - */ -void mbedtls_ssl_conf_ca_chain( mbedtls_ssl_config *conf, - mbedtls_x509_crt *ca_chain, - mbedtls_x509_crl *ca_crl ); - -#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) -/** - * \brief Set the trusted certificate callback. - * - * This API allows to register the set of trusted certificates - * through a callback, instead of a linked list as configured - * by mbedtls_ssl_conf_ca_chain(). - * - * This is useful for example in contexts where a large number - * of CAs are used, and the inefficiency of maintaining them - * in a linked list cannot be tolerated. It is also useful when - * the set of trusted CAs needs to be modified frequently. - * - * See the documentation of `mbedtls_x509_crt_ca_cb_t` for - * more information. - * - * \param conf The SSL configuration to register the callback with. - * \param f_ca_cb The trusted certificate callback to use when verifying - * certificate chains. - * \param p_ca_cb The context to be passed to \p f_ca_cb (for example, - * a reference to a trusted CA database). - * - * \note This API is incompatible with mbedtls_ssl_conf_ca_chain(): - * Any call to this function overwrites the values set through - * earlier calls to mbedtls_ssl_conf_ca_chain() or - * mbedtls_ssl_conf_ca_cb(). - * - * \note This API is incompatible with CA indication in - * CertificateRequest messages: A server-side SSL context which - * is bound to an SSL configuration that uses a CA callback - * configured via mbedtls_ssl_conf_ca_cb(), and which requires - * client authentication, will send an empty CA list in the - * corresponding CertificateRequest message. - * - * \note This API is incompatible with mbedtls_ssl_set_hs_ca_chain(): - * If an SSL context is bound to an SSL configuration which uses - * CA callbacks configured via mbedtls_ssl_conf_ca_cb(), then - * calls to mbedtls_ssl_set_hs_ca_chain() have no effect. - * - * \note The use of this API disables the use of restartable ECC - * during X.509 CRT signature verification (but doesn't affect - * other uses). - * - * \warning This API is incompatible with the use of CRLs. Any call to - * mbedtls_ssl_conf_ca_cb() unsets CRLs configured through - * earlier calls to mbedtls_ssl_conf_ca_chain(). - * - * \warning In multi-threaded environments, the callback \p f_ca_cb - * must be thread-safe, and it is the user's responsibility - * to guarantee this (for example through a mutex - * contained in the callback context pointed to by \p p_ca_cb). - */ -void mbedtls_ssl_conf_ca_cb( mbedtls_ssl_config *conf, - mbedtls_x509_crt_ca_cb_t f_ca_cb, - void *p_ca_cb ); -#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */ - -/** - * \brief Set own certificate chain and private key - * - * \note own_cert should contain in order from the bottom up your - * certificate chain. The top certificate (self-signed) - * can be omitted. - * - * \note On server, this function can be called multiple times to - * provision more than one cert/key pair (eg one ECDSA, one - * RSA with SHA-256, one RSA with SHA-1). An adequate - * certificate will be selected according to the client's - * advertised capabilities. In case multiple certificates are - * adequate, preference is given to the one set by the first - * call to this function, then second, etc. - * - * \note On client, only the first call has any effect. That is, - * only one client certificate can be provisioned. The - * server's preferences in its CertficateRequest message will - * be ignored and our only cert will be sent regardless of - * whether it matches those preferences - the server can then - * decide what it wants to do with it. - * - * \note The provided \p pk_key needs to match the public key in the - * first certificate in \p own_cert, or all handshakes using - * that certificate will fail. It is your responsibility - * to ensure that; this function will not perform any check. - * You may use mbedtls_pk_check_pair() in order to perform - * this check yourself, but be aware that this function can - * be computationally expensive on some key types. - * - * \param conf SSL configuration - * \param own_cert own public certificate chain - * \param pk_key own private key - * - * \return 0 on success or MBEDTLS_ERR_SSL_ALLOC_FAILED - */ -int mbedtls_ssl_conf_own_cert( mbedtls_ssl_config *conf, - mbedtls_x509_crt *own_cert, - mbedtls_pk_context *pk_key ); -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) -/** - * \brief Configure a pre-shared key (PSK) and identity - * to be used in PSK-based ciphersuites. - * - * \note This is mainly useful for clients. Servers will usually - * want to use \c mbedtls_ssl_conf_psk_cb() instead. - * - * \warning Currently, clients can only register a single pre-shared key. - * Calling this function or mbedtls_ssl_conf_psk_opaque() more - * than once will overwrite values configured in previous calls. - * Support for setting multiple PSKs on clients and selecting - * one based on the identity hint is not a planned feature, - * but feedback is welcomed. - * - * \param conf The SSL configuration to register the PSK with. - * \param psk The pointer to the pre-shared key to use. - * \param psk_len The length of the pre-shared key in bytes. - * \param psk_identity The pointer to the pre-shared key identity. - * \param psk_identity_len The length of the pre-shared key identity - * in bytes. - * - * \note The PSK and its identity are copied internally and - * hence need not be preserved by the caller for the lifetime - * of the SSL configuration. - * - * \return \c 0 if successful. - * \return An \c MBEDTLS_ERR_SSL_XXX error code on failure. - */ -int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf, - const unsigned char *psk, size_t psk_len, - const unsigned char *psk_identity, size_t psk_identity_len ); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -/** - * \brief Configure an opaque pre-shared key (PSK) and identity - * to be used in PSK-based ciphersuites. - * - * \note This is mainly useful for clients. Servers will usually - * want to use \c mbedtls_ssl_conf_psk_cb() instead. - * - * \warning Currently, clients can only register a single pre-shared key. - * Calling this function or mbedtls_ssl_conf_psk() more than - * once will overwrite values configured in previous calls. - * Support for setting multiple PSKs on clients and selecting - * one based on the identity hint is not a planned feature, - * but feedback is welcomed. - * - * \param conf The SSL configuration to register the PSK with. - * \param psk The identifier of the key slot holding the PSK. - * Until \p conf is destroyed or this function is successfully - * called again, the key slot \p psk must be populated with a - * key of type PSA_ALG_CATEGORY_KEY_DERIVATION whose policy - * allows its use for the key derivation algorithm applied - * in the handshake. - * \param psk_identity The pointer to the pre-shared key identity. - * \param psk_identity_len The length of the pre-shared key identity - * in bytes. - * - * \note The PSK identity hint is copied internally and hence need - * not be preserved by the caller for the lifetime of the - * SSL configuration. - * - * \return \c 0 if successful. - * \return An \c MBEDTLS_ERR_SSL_XXX error code on failure. - */ -int mbedtls_ssl_conf_psk_opaque( mbedtls_ssl_config *conf, - psa_key_handle_t psk, - const unsigned char *psk_identity, - size_t psk_identity_len ); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -/** - * \brief Set the pre-shared Key (PSK) for the current handshake. - * - * \note This should only be called inside the PSK callback, - * i.e. the function passed to \c mbedtls_ssl_conf_psk_cb(). - * - * \param ssl The SSL context to configure a PSK for. - * \param psk The pointer to the pre-shared key. - * \param psk_len The length of the pre-shared key in bytes. - * - * \return \c 0 if successful. - * \return An \c MBEDTLS_ERR_SSL_XXX error code on failure. - */ -int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl, - const unsigned char *psk, size_t psk_len ); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -/** - * \brief Set an opaque pre-shared Key (PSK) for the current handshake. - * - * \note This should only be called inside the PSK callback, - * i.e. the function passed to \c mbedtls_ssl_conf_psk_cb(). - * - * \param ssl The SSL context to configure a PSK for. - * \param psk The identifier of the key slot holding the PSK. - * For the duration of the current handshake, the key slot - * must be populated with a key of type - * PSA_ALG_CATEGORY_KEY_DERIVATION whose policy allows its - * use for the key derivation algorithm - * applied in the handshake. - * - * \return \c 0 if successful. - * \return An \c MBEDTLS_ERR_SSL_XXX error code on failure. - */ -int mbedtls_ssl_set_hs_psk_opaque( mbedtls_ssl_context *ssl, - psa_key_handle_t psk ); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -/** - * \brief Set the PSK callback (server-side only). - * - * If set, the PSK callback is called for each - * handshake where a PSK-based ciphersuite was negotiated. - * The caller provides the identity received and wants to - * receive the actual PSK data and length. - * - * The callback has the following parameters: - * - \c void*: The opaque pointer \p p_psk. - * - \c mbedtls_ssl_context*: The SSL context to which - * the operation applies. - * - \c const unsigned char*: The PSK identity - * selected by the client. - * - \c size_t: The length of the PSK identity - * selected by the client. - * - * If a valid PSK identity is found, the callback should use - * \c mbedtls_ssl_set_hs_psk() or - * \c mbedtls_ssl_set_hs_psk_opaque() - * on the SSL context to set the correct PSK and return \c 0. - * Any other return value will result in a denied PSK identity. - * - * \note If you set a PSK callback using this function, then you - * don't need to set a PSK key and identity using - * \c mbedtls_ssl_conf_psk(). - * - * \param conf The SSL configuration to register the callback with. - * \param f_psk The callback for selecting and setting the PSK based - * in the PSK identity chosen by the client. - * \param p_psk A pointer to an opaque structure to be passed to - * the callback, for example a PSK store. - */ -void mbedtls_ssl_conf_psk_cb( mbedtls_ssl_config *conf, - int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *, - size_t), - void *p_psk ); -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ - -#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C) - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) - -#if defined(MBEDTLS_DEPRECATED_WARNING) -#define MBEDTLS_DEPRECATED __attribute__((deprecated)) -#else -#define MBEDTLS_DEPRECATED -#endif - -/** - * \brief Set the Diffie-Hellman public P and G values, - * read as hexadecimal strings (server-side only) - * (Default values: MBEDTLS_DHM_RFC3526_MODP_2048_[PG]) - * - * \param conf SSL configuration - * \param dhm_P Diffie-Hellman-Merkle modulus - * \param dhm_G Diffie-Hellman-Merkle generator - * - * \deprecated Superseded by \c mbedtls_ssl_conf_dh_param_bin. - * - * \return 0 if successful - */ -MBEDTLS_DEPRECATED int mbedtls_ssl_conf_dh_param( mbedtls_ssl_config *conf, - const char *dhm_P, - const char *dhm_G ); - -#endif /* MBEDTLS_DEPRECATED_REMOVED */ - -/** - * \brief Set the Diffie-Hellman public P and G values - * from big-endian binary presentations. - * (Default values: MBEDTLS_DHM_RFC3526_MODP_2048_[PG]_BIN) - * - * \param conf SSL configuration - * \param dhm_P Diffie-Hellman-Merkle modulus in big-endian binary form - * \param P_len Length of DHM modulus - * \param dhm_G Diffie-Hellman-Merkle generator in big-endian binary form - * \param G_len Length of DHM generator - * - * \return 0 if successful - */ -int mbedtls_ssl_conf_dh_param_bin( mbedtls_ssl_config *conf, - const unsigned char *dhm_P, size_t P_len, - const unsigned char *dhm_G, size_t G_len ); - -/** - * \brief Set the Diffie-Hellman public P and G values, - * read from existing context (server-side only) - * - * \param conf SSL configuration - * \param dhm_ctx Diffie-Hellman-Merkle context - * - * \return 0 if successful - */ -int mbedtls_ssl_conf_dh_param_ctx( mbedtls_ssl_config *conf, mbedtls_dhm_context *dhm_ctx ); -#endif /* MBEDTLS_DHM_C && defined(MBEDTLS_SSL_SRV_C) */ - -#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C) -/** - * \brief Set the minimum length for Diffie-Hellman parameters. - * (Client-side only.) - * (Default: 1024 bits.) - * - * \param conf SSL configuration - * \param bitlen Minimum bit length of the DHM prime - */ -void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf, - unsigned int bitlen ); -#endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_CLI_C */ - -#if defined(MBEDTLS_ECP_C) -/** - * \brief Set the allowed curves in order of preference. - * (Default: all defined curves.) - * - * On server: this only affects selection of the ECDHE curve; - * the curves used for ECDH and ECDSA are determined by the - * list of available certificates instead. - * - * On client: this affects the list of curves offered for any - * use. The server can override our preference order. - * - * Both sides: limits the set of curves accepted for use in - * ECDHE and in the peer's end-entity certificate. - * - * \note This has no influence on which curves are allowed inside the - * certificate chains, see \c mbedtls_ssl_conf_cert_profile() - * for that. For the end-entity certificate however, the key - * will be accepted only if it is allowed both by this list - * and by the cert profile. - * - * \note This list should be ordered by decreasing preference - * (preferred curve first). - * - * \param conf SSL configuration - * \param curves Ordered list of allowed curves, - * terminated by MBEDTLS_ECP_DP_NONE. - */ -void mbedtls_ssl_conf_curves( mbedtls_ssl_config *conf, - const mbedtls_ecp_group_id *curves ); -#endif /* MBEDTLS_ECP_C */ - -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) -/** - * \brief Set the allowed hashes for signatures during the handshake. - * (Default: all available hashes except MD5.) - * - * \note This only affects which hashes are offered and can be used - * for signatures during the handshake. Hashes for message - * authentication and the TLS PRF are controlled by the - * ciphersuite, see \c mbedtls_ssl_conf_ciphersuites(). Hashes - * used for certificate signature are controlled by the - * verification profile, see \c mbedtls_ssl_conf_cert_profile(). - * - * \note This list should be ordered by decreasing preference - * (preferred hash first). - * - * \param conf SSL configuration - * \param hashes Ordered list of allowed signature hashes, - * terminated by \c MBEDTLS_MD_NONE. - */ -void mbedtls_ssl_conf_sig_hashes( mbedtls_ssl_config *conf, - const int *hashes ); -#endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -/** - * \brief Set or reset the hostname to check against the received - * server certificate. It sets the ServerName TLS extension, - * too, if that extension is enabled. (client-side only) - * - * \param ssl SSL context - * \param hostname the server hostname, may be NULL to clear hostname - - * \note Maximum hostname length MBEDTLS_SSL_MAX_HOST_NAME_LEN. - * - * \return 0 if successful, MBEDTLS_ERR_SSL_ALLOC_FAILED on - * allocation failure, MBEDTLS_ERR_SSL_BAD_INPUT_DATA on - * too long input hostname. - * - * Hostname set to the one provided on success (cleared - * when NULL). On allocation failure hostname is cleared. - * On too long input failure, old hostname is unchanged. - */ -int mbedtls_ssl_set_hostname( mbedtls_ssl_context *ssl, const char *hostname ); -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) -/** - * \brief Set own certificate and key for the current handshake - * - * \note Same as \c mbedtls_ssl_conf_own_cert() but for use within - * the SNI callback. - * - * \param ssl SSL context - * \param own_cert own public certificate chain - * \param pk_key own private key - * - * \return 0 on success or MBEDTLS_ERR_SSL_ALLOC_FAILED - */ -int mbedtls_ssl_set_hs_own_cert( mbedtls_ssl_context *ssl, - mbedtls_x509_crt *own_cert, - mbedtls_pk_context *pk_key ); - -/** - * \brief Set the data required to verify peer certificate for the - * current handshake - * - * \note Same as \c mbedtls_ssl_conf_ca_chain() but for use within - * the SNI callback. - * - * \param ssl SSL context - * \param ca_chain trusted CA chain (meaning all fully trusted top-level CAs) - * \param ca_crl trusted CA CRLs - */ -void mbedtls_ssl_set_hs_ca_chain( mbedtls_ssl_context *ssl, - mbedtls_x509_crt *ca_chain, - mbedtls_x509_crl *ca_crl ); - -/** - * \brief Set authmode for the current handshake. - * - * \note Same as \c mbedtls_ssl_conf_authmode() but for use within - * the SNI callback. - * - * \param ssl SSL context - * \param authmode MBEDTLS_SSL_VERIFY_NONE, MBEDTLS_SSL_VERIFY_OPTIONAL or - * MBEDTLS_SSL_VERIFY_REQUIRED - */ -void mbedtls_ssl_set_hs_authmode( mbedtls_ssl_context *ssl, - int authmode ); - -/** - * \brief Set server side ServerName TLS extension callback - * (optional, server-side only). - * - * If set, the ServerName callback is called whenever the - * server receives a ServerName TLS extension from the client - * during a handshake. The ServerName callback has the - * following parameters: (void *parameter, mbedtls_ssl_context *ssl, - * const unsigned char *hostname, size_t len). If a suitable - * certificate is found, the callback must set the - * certificate(s) and key(s) to use with \c - * mbedtls_ssl_set_hs_own_cert() (can be called repeatedly), - * and may optionally adjust the CA and associated CRL with \c - * mbedtls_ssl_set_hs_ca_chain() as well as the client - * authentication mode with \c mbedtls_ssl_set_hs_authmode(), - * then must return 0. If no matching name is found, the - * callback must either set a default cert, or - * return non-zero to abort the handshake at this point. - * - * \param conf SSL configuration - * \param f_sni verification function - * \param p_sni verification parameter - */ -void mbedtls_ssl_conf_sni( mbedtls_ssl_config *conf, - int (*f_sni)(void *, mbedtls_ssl_context *, const unsigned char *, - size_t), - void *p_sni ); -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -/** - * \brief Set the EC J-PAKE password for current handshake. - * - * \note An internal copy is made, and destroyed as soon as the - * handshake is completed, or when the SSL context is reset or - * freed. - * - * \note The SSL context needs to be already set up. The right place - * to call this function is between \c mbedtls_ssl_setup() or - * \c mbedtls_ssl_reset() and \c mbedtls_ssl_handshake(). - * - * \param ssl SSL context - * \param pw EC J-PAKE password (pre-shared secret) - * \param pw_len length of pw in bytes - * - * \return 0 on success, or a negative error code. - */ -int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl, - const unsigned char *pw, - size_t pw_len ); -#endif /*MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_SSL_ALPN) -/** - * \brief Set the supported Application Layer Protocols. - * - * \param conf SSL configuration - * \param protos Pointer to a NULL-terminated list of supported protocols, - * in decreasing preference order. The pointer to the list is - * recorded by the library for later reference as required, so - * the lifetime of the table must be atleast as long as the - * lifetime of the SSL configuration structure. - * - * \return 0 on success, or MBEDTLS_ERR_SSL_BAD_INPUT_DATA. - */ -int mbedtls_ssl_conf_alpn_protocols( mbedtls_ssl_config *conf, const char **protos ); - -/** - * \brief Get the name of the negotiated Application Layer Protocol. - * This function should be called after the handshake is - * completed. - * - * \param ssl SSL context - * - * \return Protcol name, or NULL if no protocol was negotiated. - */ -const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl ); -#endif /* MBEDTLS_SSL_ALPN */ - -/** - * \brief Set the maximum supported version sent from the client side - * and/or accepted at the server side - * (Default: MBEDTLS_SSL_MAX_MAJOR_VERSION, MBEDTLS_SSL_MAX_MINOR_VERSION) - * - * \note This ignores ciphersuites from higher versions. - * - * \note With DTLS, use MBEDTLS_SSL_MINOR_VERSION_2 for DTLS 1.0 and - * MBEDTLS_SSL_MINOR_VERSION_3 for DTLS 1.2 - * - * \param conf SSL configuration - * \param major Major version number (only MBEDTLS_SSL_MAJOR_VERSION_3 supported) - * \param minor Minor version number (MBEDTLS_SSL_MINOR_VERSION_0, - * MBEDTLS_SSL_MINOR_VERSION_1 and MBEDTLS_SSL_MINOR_VERSION_2, - * MBEDTLS_SSL_MINOR_VERSION_3 supported) - */ -void mbedtls_ssl_conf_max_version( mbedtls_ssl_config *conf, int major, int minor ); - -/** - * \brief Set the minimum accepted SSL/TLS protocol version - * (Default: TLS 1.0) - * - * \note Input outside of the SSL_MAX_XXXXX_VERSION and - * SSL_MIN_XXXXX_VERSION range is ignored. - * - * \note MBEDTLS_SSL_MINOR_VERSION_0 (SSL v3) should be avoided. - * - * \note With DTLS, use MBEDTLS_SSL_MINOR_VERSION_2 for DTLS 1.0 and - * MBEDTLS_SSL_MINOR_VERSION_3 for DTLS 1.2 - * - * \param conf SSL configuration - * \param major Major version number (only MBEDTLS_SSL_MAJOR_VERSION_3 supported) - * \param minor Minor version number (MBEDTLS_SSL_MINOR_VERSION_0, - * MBEDTLS_SSL_MINOR_VERSION_1 and MBEDTLS_SSL_MINOR_VERSION_2, - * MBEDTLS_SSL_MINOR_VERSION_3 supported) - */ -void mbedtls_ssl_conf_min_version( mbedtls_ssl_config *conf, int major, int minor ); - -#if defined(MBEDTLS_SSL_FALLBACK_SCSV) && defined(MBEDTLS_SSL_CLI_C) -/** - * \brief Set the fallback flag (client-side only). - * (Default: MBEDTLS_SSL_IS_NOT_FALLBACK). - * - * \note Set to MBEDTLS_SSL_IS_FALLBACK when preparing a fallback - * connection, that is a connection with max_version set to a - * lower value than the value you're willing to use. Such - * fallback connections are not recommended but are sometimes - * necessary to interoperate with buggy (version-intolerant) - * servers. - * - * \warning You should NOT set this to MBEDTLS_SSL_IS_FALLBACK for - * non-fallback connections! This would appear to work for a - * while, then cause failures when the server is upgraded to - * support a newer TLS version. - * - * \param conf SSL configuration - * \param fallback MBEDTLS_SSL_IS_NOT_FALLBACK or MBEDTLS_SSL_IS_FALLBACK - */ -void mbedtls_ssl_conf_fallback( mbedtls_ssl_config *conf, char fallback ); -#endif /* MBEDTLS_SSL_FALLBACK_SCSV && MBEDTLS_SSL_CLI_C */ - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) -/** - * \brief Enable or disable Encrypt-then-MAC - * (Default: MBEDTLS_SSL_ETM_ENABLED) - * - * \note This should always be enabled, it is a security - * improvement, and should not cause any interoperability - * issue (used only if the peer supports it too). - * - * \param conf SSL configuration - * \param etm MBEDTLS_SSL_ETM_ENABLED or MBEDTLS_SSL_ETM_DISABLED - */ -void mbedtls_ssl_conf_encrypt_then_mac( mbedtls_ssl_config *conf, char etm ); -#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) -/** - * \brief Enable or disable Extended Master Secret negotiation. - * (Default: MBEDTLS_SSL_EXTENDED_MS_ENABLED) - * - * \note This should always be enabled, it is a security fix to the - * protocol, and should not cause any interoperability issue - * (used only if the peer supports it too). - * - * \param conf SSL configuration - * \param ems MBEDTLS_SSL_EXTENDED_MS_ENABLED or MBEDTLS_SSL_EXTENDED_MS_DISABLED - */ -void mbedtls_ssl_conf_extended_master_secret( mbedtls_ssl_config *conf, char ems ); -#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ - -#if defined(MBEDTLS_ARC4_C) -/** - * \brief Disable or enable support for RC4 - * (Default: MBEDTLS_SSL_ARC4_DISABLED) - * - * \warning Use of RC4 in DTLS/TLS has been prohibited by RFC 7465 - * for security reasons. Use at your own risk. - * - * \note This function is deprecated and will likely be removed in - * a future version of the library. - * RC4 is disabled by default at compile time and needs to be - * actively enabled for use with legacy systems. - * - * \param conf SSL configuration - * \param arc4 MBEDTLS_SSL_ARC4_ENABLED or MBEDTLS_SSL_ARC4_DISABLED - */ -void mbedtls_ssl_conf_arc4_support( mbedtls_ssl_config *conf, char arc4 ); -#endif /* MBEDTLS_ARC4_C */ - -#if defined(MBEDTLS_SSL_SRV_C) -/** - * \brief Whether to send a list of acceptable CAs in - * CertificateRequest messages. - * (Default: do send) - * - * \param conf SSL configuration - * \param cert_req_ca_list MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED or - * MBEDTLS_SSL_CERT_REQ_CA_LIST_DISABLED - */ -void mbedtls_ssl_conf_cert_req_ca_list( mbedtls_ssl_config *conf, - char cert_req_ca_list ); -#endif /* MBEDTLS_SSL_SRV_C */ - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) -/** - * \brief Set the maximum fragment length to emit and/or negotiate - * (Default: the smaller of MBEDTLS_SSL_IN_CONTENT_LEN and - * MBEDTLS_SSL_OUT_CONTENT_LEN, usually 2^14 bytes) - * (Server: set maximum fragment length to emit, - * usually negotiated by the client during handshake - * (Client: set maximum fragment length to emit *and* - * negotiate with the server during handshake) - * - * \note With TLS, this currently only affects ApplicationData (sent - * with \c mbedtls_ssl_read()), not handshake messages. - * With DTLS, this affects both ApplicationData and handshake. - * - * \note This sets the maximum length for a record's payload, - * excluding record overhead that will be added to it, see - * \c mbedtls_ssl_get_record_expansion(). - * - * \note For DTLS, it is also possible to set a limit for the total - * size of daragrams passed to the transport layer, including - * record overhead, see \c mbedtls_ssl_set_mtu(). - * - * \param conf SSL configuration - * \param mfl_code Code for maximum fragment length (allowed values: - * MBEDTLS_SSL_MAX_FRAG_LEN_512, MBEDTLS_SSL_MAX_FRAG_LEN_1024, - * MBEDTLS_SSL_MAX_FRAG_LEN_2048, MBEDTLS_SSL_MAX_FRAG_LEN_4096) - * - * \return 0 if successful or MBEDTLS_ERR_SSL_BAD_INPUT_DATA - */ -int mbedtls_ssl_conf_max_frag_len( mbedtls_ssl_config *conf, unsigned char mfl_code ); -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) -/** - * \brief Activate negotiation of truncated HMAC - * (Default: MBEDTLS_SSL_TRUNC_HMAC_DISABLED) - * - * \param conf SSL configuration - * \param truncate Enable or disable (MBEDTLS_SSL_TRUNC_HMAC_ENABLED or - * MBEDTLS_SSL_TRUNC_HMAC_DISABLED) - */ -void mbedtls_ssl_conf_truncated_hmac( mbedtls_ssl_config *conf, int truncate ); -#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ - -#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) -/** - * \brief Enable / Disable 1/n-1 record splitting - * (Default: MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED) - * - * \note Only affects SSLv3 and TLS 1.0, not higher versions. - * Does not affect non-CBC ciphersuites in any version. - * - * \param conf SSL configuration - * \param split MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED or - * MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED - */ -void mbedtls_ssl_conf_cbc_record_splitting( mbedtls_ssl_config *conf, char split ); -#endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) -/** - * \brief Enable / Disable session tickets (client only). - * (Default: MBEDTLS_SSL_SESSION_TICKETS_ENABLED.) - * - * \note On server, use \c mbedtls_ssl_conf_session_tickets_cb(). - * - * \param conf SSL configuration - * \param use_tickets Enable or disable (MBEDTLS_SSL_SESSION_TICKETS_ENABLED or - * MBEDTLS_SSL_SESSION_TICKETS_DISABLED) - */ -void mbedtls_ssl_conf_session_tickets( mbedtls_ssl_config *conf, int use_tickets ); -#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */ - -#if defined(MBEDTLS_SSL_RENEGOTIATION) -/** - * \brief Enable / Disable renegotiation support for connection when - * initiated by peer - * (Default: MBEDTLS_SSL_RENEGOTIATION_DISABLED) - * - * \warning It is recommended to always disable renegotation unless you - * know you need it and you know what you're doing. In the - * past, there have been several issues associated with - * renegotiation or a poor understanding of its properties. - * - * \note Server-side, enabling renegotiation also makes the server - * susceptible to a resource DoS by a malicious client. - * - * \param conf SSL configuration - * \param renegotiation Enable or disable (MBEDTLS_SSL_RENEGOTIATION_ENABLED or - * MBEDTLS_SSL_RENEGOTIATION_DISABLED) - */ -void mbedtls_ssl_conf_renegotiation( mbedtls_ssl_config *conf, int renegotiation ); -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - -/** - * \brief Prevent or allow legacy renegotiation. - * (Default: MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION) - * - * MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION allows connections to - * be established even if the peer does not support - * secure renegotiation, but does not allow renegotiation - * to take place if not secure. - * (Interoperable and secure option) - * - * MBEDTLS_SSL_LEGACY_ALLOW_RENEGOTIATION allows renegotiations - * with non-upgraded peers. Allowing legacy renegotiation - * makes the connection vulnerable to specific man in the - * middle attacks. (See RFC 5746) - * (Most interoperable and least secure option) - * - * MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE breaks off connections - * if peer does not support secure renegotiation. Results - * in interoperability issues with non-upgraded peers - * that do not support renegotiation altogether. - * (Most secure option, interoperability issues) - * - * \param conf SSL configuration - * \param allow_legacy Prevent or allow (SSL_NO_LEGACY_RENEGOTIATION, - * SSL_ALLOW_LEGACY_RENEGOTIATION or - * MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE) - */ -void mbedtls_ssl_conf_legacy_renegotiation( mbedtls_ssl_config *conf, int allow_legacy ); - -#if defined(MBEDTLS_SSL_RENEGOTIATION) -/** - * \brief Enforce renegotiation requests. - * (Default: enforced, max_records = 16) - * - * When we request a renegotiation, the peer can comply or - * ignore the request. This function allows us to decide - * whether to enforce our renegotiation requests by closing - * the connection if the peer doesn't comply. - * - * However, records could already be in transit from the peer - * when the request is emitted. In order to increase - * reliability, we can accept a number of records before the - * expected handshake records. - * - * The optimal value is highly dependent on the specific usage - * scenario. - * - * \note With DTLS and server-initiated renegotiation, the - * HelloRequest is retransmited every time mbedtls_ssl_read() times - * out or receives Application Data, until: - * - max_records records have beens seen, if it is >= 0, or - * - the number of retransmits that would happen during an - * actual handshake has been reached. - * Please remember the request might be lost a few times - * if you consider setting max_records to a really low value. - * - * \warning On client, the grace period can only happen during - * mbedtls_ssl_read(), as opposed to mbedtls_ssl_write() and mbedtls_ssl_renegotiate() - * which always behave as if max_record was 0. The reason is, - * if we receive application data from the server, we need a - * place to write it, which only happens during mbedtls_ssl_read(). - * - * \param conf SSL configuration - * \param max_records Use MBEDTLS_SSL_RENEGOTIATION_NOT_ENFORCED if you don't want to - * enforce renegotiation, or a non-negative value to enforce - * it but allow for a grace period of max_records records. - */ -void mbedtls_ssl_conf_renegotiation_enforced( mbedtls_ssl_config *conf, int max_records ); - -/** - * \brief Set record counter threshold for periodic renegotiation. - * (Default: 2^48 - 1) - * - * Renegotiation is automatically triggered when a record - * counter (outgoing or ingoing) crosses the defined - * threshold. The default value is meant to prevent the - * connection from being closed when the counter is about to - * reached its maximal value (it is not allowed to wrap). - * - * Lower values can be used to enforce policies such as "keys - * must be refreshed every N packets with cipher X". - * - * The renegotiation period can be disabled by setting - * conf->disable_renegotiation to - * MBEDTLS_SSL_RENEGOTIATION_DISABLED. - * - * \note When the configured transport is - * MBEDTLS_SSL_TRANSPORT_DATAGRAM the maximum renegotiation - * period is 2^48 - 1, and for MBEDTLS_SSL_TRANSPORT_STREAM, - * the maximum renegotiation period is 2^64 - 1. - * - * \param conf SSL configuration - * \param period The threshold value: a big-endian 64-bit number. - */ -void mbedtls_ssl_conf_renegotiation_period( mbedtls_ssl_config *conf, - const unsigned char period[8] ); -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - -/** - * \brief Check if there is data already read from the - * underlying transport but not yet processed. - * - * \param ssl SSL context - * - * \return 0 if nothing's pending, 1 otherwise. - * - * \note This is different in purpose and behaviour from - * \c mbedtls_ssl_get_bytes_avail in that it considers - * any kind of unprocessed data, not only unread - * application data. If \c mbedtls_ssl_get_bytes - * returns a non-zero value, this function will - * also signal pending data, but the converse does - * not hold. For example, in DTLS there might be - * further records waiting to be processed from - * the current underlying transport's datagram. - * - * \note If this function returns 1 (data pending), this - * does not imply that a subsequent call to - * \c mbedtls_ssl_read will provide any data; - * e.g., the unprocessed data might turn out - * to be an alert or a handshake message. - * - * \note This function is useful in the following situation: - * If the SSL/TLS module successfully returns from an - * operation - e.g. a handshake or an application record - * read - and you're awaiting incoming data next, you - * must not immediately idle on the underlying transport - * to have data ready, but you need to check the value - * of this function first. The reason is that the desired - * data might already be read but not yet processed. - * If, in contrast, a previous call to the SSL/TLS module - * returned MBEDTLS_ERR_SSL_WANT_READ, it is not necessary - * to call this function, as the latter error code entails - * that all internal data has been processed. - * - */ -int mbedtls_ssl_check_pending( const mbedtls_ssl_context *ssl ); - -/** - * \brief Return the number of application data bytes - * remaining to be read from the current record. - * - * \param ssl SSL context - * - * \return How many bytes are available in the application - * data record read buffer. - * - * \note When working over a datagram transport, this is - * useful to detect the current datagram's boundary - * in case \c mbedtls_ssl_read has written the maximal - * amount of data fitting into the input buffer. - * - */ -size_t mbedtls_ssl_get_bytes_avail( const mbedtls_ssl_context *ssl ); - -/** - * \brief Return the result of the certificate verification - * - * \param ssl The SSL context to use. - * - * \return \c 0 if the certificate verification was successful. - * \return \c -1u if the result is not available. This may happen - * e.g. if the handshake aborts early, or a verification - * callback returned a fatal error. - * \return A bitwise combination of \c MBEDTLS_X509_BADCERT_XXX - * and \c MBEDTLS_X509_BADCRL_XXX failure flags; see x509.h. - */ -uint32_t mbedtls_ssl_get_verify_result( const mbedtls_ssl_context *ssl ); - -/** - * \brief Return the name of the current ciphersuite - * - * \param ssl SSL context - * - * \return a string containing the ciphersuite name - */ -const char *mbedtls_ssl_get_ciphersuite( const mbedtls_ssl_context *ssl ); - -/** - * \brief Return the current SSL version (SSLv3/TLSv1/etc) - * - * \param ssl SSL context - * - * \return a string containing the SSL version - */ -const char *mbedtls_ssl_get_version( const mbedtls_ssl_context *ssl ); - -/** - * \brief Return the (maximum) number of bytes added by the record - * layer: header + encryption/MAC overhead (inc. padding) - * - * \note This function is not available (always returns an error) - * when record compression is enabled. - * - * \param ssl SSL context - * - * \return Current maximum record expansion in bytes, or - * MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE if compression is - * enabled, which makes expansion much less predictable - */ -int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl ); - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) -/** - * \brief Return the maximum fragment length (payload, in bytes). - * This is the value negotiated with peer if any, - * or the locally configured value. - * - * \sa mbedtls_ssl_conf_max_frag_len() - * \sa mbedtls_ssl_get_max_record_payload() - * - * \param ssl SSL context - * - * \return Current maximum fragment length. - */ -size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl ); -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -/** - * \brief Return the current maximum outgoing record payload in bytes. - * This takes into account the config.h setting \c - * MBEDTLS_SSL_OUT_CONTENT_LEN, the configured and negotiated - * max fragment length extension if used, and for DTLS the - * path MTU as configured and current record expansion. - * - * \note With DTLS, \c mbedtls_ssl_write() will return an error if - * called with a larger length value. - * With TLS, \c mbedtls_ssl_write() will fragment the input if - * necessary and return the number of bytes written; it is up - * to the caller to call \c mbedtls_ssl_write() again in - * order to send the remaining bytes if any. - * - * \note This function is not available (always returns an error) - * when record compression is enabled. - * - * \sa mbedtls_ssl_set_mtu() - * \sa mbedtls_ssl_get_max_frag_len() - * \sa mbedtls_ssl_get_record_expansion() - * - * \param ssl SSL context - * - * \return Current maximum payload for an outgoing record, - * or a negative error code. - */ -int mbedtls_ssl_get_max_out_record_payload( const mbedtls_ssl_context *ssl ); - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -/** - * \brief Return the peer certificate from the current connection. - * - * \param ssl The SSL context to use. This must be initialized and setup. - * - * \return The current peer certificate, if available. - * The returned certificate is owned by the SSL context and - * is valid only until the next call to the SSL API. - * \return \c NULL if no peer certificate is available. This might - * be because the chosen ciphersuite doesn't use CRTs - * (PSK-based ciphersuites, for example), or because - * #MBEDTLS_SSL_KEEP_PEER_CERTIFICATE has been disabled, - * allowing the stack to free the peer's CRT to save memory. - * - * \note For one-time inspection of the peer's certificate during - * the handshake, consider registering an X.509 CRT verification - * callback through mbedtls_ssl_conf_verify() instead of calling - * this function. Using mbedtls_ssl_conf_verify() also comes at - * the benefit of allowing you to influence the verification - * process, for example by masking expected and tolerated - * verification failures. - * - * \warning You must not use the pointer returned by this function - * after any further call to the SSL API, including - * mbedtls_ssl_read() and mbedtls_ssl_write(); this is - * because the pointer might change during renegotiation, - * which happens transparently to the user. - * If you want to use the certificate across API calls, - * you must make a copy. - */ -const mbedtls_x509_crt *mbedtls_ssl_get_peer_cert( const mbedtls_ssl_context *ssl ); -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_SSL_CLI_C) -/** - * \brief Save session in order to resume it later (client-side only) - * Session data is copied to presented session structure. - * - * - * \param ssl SSL context - * \param session session context - * - * \return 0 if successful, - * MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed, - * MBEDTLS_ERR_SSL_BAD_INPUT_DATA if used server-side or - * arguments are otherwise invalid. - * - * \note Only the server certificate is copied, and not the full chain, - * so you should not attempt to validate the certificate again - * by calling \c mbedtls_x509_crt_verify() on it. - * Instead, you should use the results from the verification - * in the original handshake by calling \c mbedtls_ssl_get_verify_result() - * after loading the session again into a new SSL context - * using \c mbedtls_ssl_set_session(). - * - * \note Once the session object is not needed anymore, you should - * free it by calling \c mbedtls_ssl_session_free(). - * - * \sa mbedtls_ssl_set_session() - */ -int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl, mbedtls_ssl_session *session ); -#endif /* MBEDTLS_SSL_CLI_C */ - -/** - * \brief Perform the SSL handshake - * - * \param ssl SSL context - * - * \return \c 0 if successful. - * \return #MBEDTLS_ERR_SSL_WANT_READ or #MBEDTLS_ERR_SSL_WANT_WRITE - * if the handshake is incomplete and waiting for data to - * be available for reading from or writing to the underlying - * transport - in this case you must call this function again - * when the underlying transport is ready for the operation. - * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if an asynchronous - * operation is in progress (see - * mbedtls_ssl_conf_async_private_cb()) - in this case you - * must call this function again when the operation is ready. - * \return #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS if a cryptographic - * operation is in progress (see mbedtls_ecp_set_max_ops()) - - * in this case you must call this function again to complete - * the handshake when you're done attending other tasks. - * \return #MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED if DTLS is in use - * and the client did not demonstrate reachability yet - in - * this case you must stop using the context (see below). - * \return Another SSL error code - in this case you must stop using - * the context (see below). - * - * \warning If this function returns something other than - * \c 0, - * #MBEDTLS_ERR_SSL_WANT_READ, - * #MBEDTLS_ERR_SSL_WANT_WRITE, - * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or - * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, - * you must stop using the SSL context for reading or writing, - * and either free it or call \c mbedtls_ssl_session_reset() - * on it before re-using it for a new connection; the current - * connection must be closed. - * - * \note If DTLS is in use, then you may choose to handle - * #MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED specially for logging - * purposes, as it is an expected return value rather than an - * actual error, but you still need to reset/free the context. - * - * \note Remarks regarding event-driven DTLS: - * If the function returns #MBEDTLS_ERR_SSL_WANT_READ, no datagram - * from the underlying transport layer is currently being processed, - * and it is safe to idle until the timer or the underlying transport - * signal a new event. This is not true for a successful handshake, - * in which case the datagram of the underlying transport that is - * currently being processed might or might not contain further - * DTLS records. - */ -int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl ); - -/** - * \brief Perform a single step of the SSL handshake - * - * \note The state of the context (ssl->state) will be at - * the next state after this function returns \c 0. Do not - * call this function if state is MBEDTLS_SSL_HANDSHAKE_OVER. - * - * \param ssl SSL context - * - * \return See mbedtls_ssl_handshake(). - * - * \warning If this function returns something other than \c 0, - * #MBEDTLS_ERR_SSL_WANT_READ, #MBEDTLS_ERR_SSL_WANT_WRITE, - * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or - * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, you must stop using - * the SSL context for reading or writing, and either free it - * or call \c mbedtls_ssl_session_reset() on it before - * re-using it for a new connection; the current connection - * must be closed. - */ -int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl ); - -#if defined(MBEDTLS_SSL_RENEGOTIATION) -/** - * \brief Initiate an SSL renegotiation on the running connection. - * Client: perform the renegotiation right now. - * Server: request renegotiation, which will be performed - * during the next call to mbedtls_ssl_read() if honored by - * client. - * - * \param ssl SSL context - * - * \return 0 if successful, or any mbedtls_ssl_handshake() return - * value except #MBEDTLS_ERR_SSL_CLIENT_RECONNECT that can't - * happen during a renegotiation. - * - * \warning If this function returns something other than \c 0, - * #MBEDTLS_ERR_SSL_WANT_READ, #MBEDTLS_ERR_SSL_WANT_WRITE, - * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or - * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, you must stop using - * the SSL context for reading or writing, and either free it - * or call \c mbedtls_ssl_session_reset() on it before - * re-using it for a new connection; the current connection - * must be closed. - * - */ -int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl ); -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - -/** - * \brief Read at most 'len' application data bytes - * - * \param ssl SSL context - * \param buf buffer that will hold the data - * \param len maximum number of bytes to read - * - * \return The (positive) number of bytes read if successful. - * \return \c 0 if the read end of the underlying transport was closed - * - in this case you must stop using the context (see below). - * \return #MBEDTLS_ERR_SSL_WANT_READ or #MBEDTLS_ERR_SSL_WANT_WRITE - * if the handshake is incomplete and waiting for data to - * be available for reading from or writing to the underlying - * transport - in this case you must call this function again - * when the underlying transport is ready for the operation. - * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if an asynchronous - * operation is in progress (see - * mbedtls_ssl_conf_async_private_cb()) - in this case you - * must call this function again when the operation is ready. - * \return #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS if a cryptographic - * operation is in progress (see mbedtls_ecp_set_max_ops()) - - * in this case you must call this function again to complete - * the handshake when you're done attending other tasks. - * \return #MBEDTLS_ERR_SSL_CLIENT_RECONNECT if we're at the server - * side of a DTLS connection and the client is initiating a - * new connection using the same source port. See below. - * \return Another SSL error code - in this case you must stop using - * the context (see below). - * - * \warning If this function returns something other than - * a positive value, - * #MBEDTLS_ERR_SSL_WANT_READ, - * #MBEDTLS_ERR_SSL_WANT_WRITE, - * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS, - * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or - * #MBEDTLS_ERR_SSL_CLIENT_RECONNECT, - * you must stop using the SSL context for reading or writing, - * and either free it or call \c mbedtls_ssl_session_reset() - * on it before re-using it for a new connection; the current - * connection must be closed. - * - * \note When this function returns #MBEDTLS_ERR_SSL_CLIENT_RECONNECT - * (which can only happen server-side), it means that a client - * is initiating a new connection using the same source port. - * You can either treat that as a connection close and wait - * for the client to resend a ClientHello, or directly - * continue with \c mbedtls_ssl_handshake() with the same - * context (as it has been reset internally). Either way, you - * must make sure this is seen by the application as a new - * connection: application state, if any, should be reset, and - * most importantly the identity of the client must be checked - * again. WARNING: not validating the identity of the client - * again, or not transmitting the new identity to the - * application layer, would allow authentication bypass! - * - * \note Remarks regarding event-driven DTLS: - * - If the function returns #MBEDTLS_ERR_SSL_WANT_READ, no datagram - * from the underlying transport layer is currently being processed, - * and it is safe to idle until the timer or the underlying transport - * signal a new event. - * - This function may return MBEDTLS_ERR_SSL_WANT_READ even if data was - * initially available on the underlying transport, as this data may have - * been only e.g. duplicated messages or a renegotiation request. - * Therefore, you must be prepared to receive MBEDTLS_ERR_SSL_WANT_READ even - * when reacting to an incoming-data event from the underlying transport. - * - On success, the datagram of the underlying transport that is currently - * being processed may contain further DTLS records. You should call - * \c mbedtls_ssl_check_pending to check for remaining records. - * - */ -int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ); - -/** - * \brief Try to write exactly 'len' application data bytes - * - * \warning This function will do partial writes in some cases. If the - * return value is non-negative but less than length, the - * function must be called again with updated arguments: - * buf + ret, len - ret (if ret is the return value) until - * it returns a value equal to the last 'len' argument. - * - * \param ssl SSL context - * \param buf buffer holding the data - * \param len how many bytes must be written - * - * \return The (non-negative) number of bytes actually written if - * successful (may be less than \p len). - * \return #MBEDTLS_ERR_SSL_WANT_READ or #MBEDTLS_ERR_SSL_WANT_WRITE - * if the handshake is incomplete and waiting for data to - * be available for reading from or writing to the underlying - * transport - in this case you must call this function again - * when the underlying transport is ready for the operation. - * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if an asynchronous - * operation is in progress (see - * mbedtls_ssl_conf_async_private_cb()) - in this case you - * must call this function again when the operation is ready. - * \return #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS if a cryptographic - * operation is in progress (see mbedtls_ecp_set_max_ops()) - - * in this case you must call this function again to complete - * the handshake when you're done attending other tasks. - * \return Another SSL error code - in this case you must stop using - * the context (see below). - * - * \warning If this function returns something other than - * a non-negative value, - * #MBEDTLS_ERR_SSL_WANT_READ, - * #MBEDTLS_ERR_SSL_WANT_WRITE, - * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or - * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, - * you must stop using the SSL context for reading or writing, - * and either free it or call \c mbedtls_ssl_session_reset() - * on it before re-using it for a new connection; the current - * connection must be closed. - * - * \note When this function returns #MBEDTLS_ERR_SSL_WANT_WRITE/READ, - * it must be called later with the *same* arguments, - * until it returns a value greater that or equal to 0. When - * the function returns #MBEDTLS_ERR_SSL_WANT_WRITE there may be - * some partial data in the output buffer, however this is not - * yet sent. - * - * \note If the requested length is greater than the maximum - * fragment length (either the built-in limit or the one set - * or negotiated with the peer), then: - * - with TLS, less bytes than requested are written. - * - with DTLS, MBEDTLS_ERR_SSL_BAD_INPUT_DATA is returned. - * \c mbedtls_ssl_get_max_frag_len() may be used to query the - * active maximum fragment length. - * - * \note Attempting to write 0 bytes will result in an empty TLS - * application record being sent. - */ -int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len ); - -/** - * \brief Send an alert message - * - * \param ssl SSL context - * \param level The alert level of the message - * (MBEDTLS_SSL_ALERT_LEVEL_WARNING or MBEDTLS_SSL_ALERT_LEVEL_FATAL) - * \param message The alert message (SSL_ALERT_MSG_*) - * - * \return 0 if successful, or a specific SSL error code. - * - * \note If this function returns something other than 0 or - * MBEDTLS_ERR_SSL_WANT_READ/WRITE, you must stop using - * the SSL context for reading or writing, and either free it or - * call \c mbedtls_ssl_session_reset() on it before re-using it - * for a new connection; the current connection must be closed. - */ -int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl, - unsigned char level, - unsigned char message ); -/** - * \brief Notify the peer that the connection is being closed - * - * \param ssl SSL context - * - * \return 0 if successful, or a specific SSL error code. - * - * \note If this function returns something other than 0 or - * MBEDTLS_ERR_SSL_WANT_READ/WRITE, you must stop using - * the SSL context for reading or writing, and either free it or - * call \c mbedtls_ssl_session_reset() on it before re-using it - * for a new connection; the current connection must be closed. - */ -int mbedtls_ssl_close_notify( mbedtls_ssl_context *ssl ); - -/** - * \brief Free referenced items in an SSL context and clear memory - * - * \param ssl SSL context - */ -void mbedtls_ssl_free( mbedtls_ssl_context *ssl ); - -/** - * \brief Initialize an SSL configuration context - * Just makes the context ready for - * mbedtls_ssl_config_defaults() or mbedtls_ssl_config_free(). - * - * \note You need to call mbedtls_ssl_config_defaults() unless you - * manually set all of the relevant fields yourself. - * - * \param conf SSL configuration context - */ -void mbedtls_ssl_config_init( mbedtls_ssl_config *conf ); - -/** - * \brief Load reasonnable default SSL configuration values. - * (You need to call mbedtls_ssl_config_init() first.) - * - * \param conf SSL configuration context - * \param endpoint MBEDTLS_SSL_IS_CLIENT or MBEDTLS_SSL_IS_SERVER - * \param transport MBEDTLS_SSL_TRANSPORT_STREAM for TLS, or - * MBEDTLS_SSL_TRANSPORT_DATAGRAM for DTLS - * \param preset a MBEDTLS_SSL_PRESET_XXX value - * - * \note See \c mbedtls_ssl_conf_transport() for notes on DTLS. - * - * \return 0 if successful, or - * MBEDTLS_ERR_XXX_ALLOC_FAILED on memory allocation error. - */ -int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, - int endpoint, int transport, int preset ); - -/** - * \brief Free an SSL configuration context - * - * \param conf SSL configuration context - */ -void mbedtls_ssl_config_free( mbedtls_ssl_config *conf ); - -/** - * \brief Initialize SSL session structure - * - * \param session SSL session - */ -void mbedtls_ssl_session_init( mbedtls_ssl_session *session ); - -/** - * \brief Free referenced items in an SSL session including the - * peer certificate and clear memory - * - * \note A session object can be freed even if the SSL context - * that was used to retrieve the session is still in use. - * - * \param session SSL session - */ -void mbedtls_ssl_session_free( mbedtls_ssl_session *session ); - -#ifdef __cplusplus -} -#endif - -#endif /* ssl.h */ diff --git a/include/mbedtls/ssl_cache.h b/include/mbedtls/ssl_cache.h deleted file mode 100644 index 84254d3d1..000000000 --- a/include/mbedtls/ssl_cache.h +++ /dev/null @@ -1,151 +0,0 @@ -/** - * \file ssl_cache.h - * - * \brief SSL session cache implementation - */ -/* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -#ifndef MBEDTLS_SSL_CACHE_H -#define MBEDTLS_SSL_CACHE_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "ssl.h" - -#if defined(MBEDTLS_THREADING_C) -#include "threading.h" -#endif - -/** - * \name SECTION: Module settings - * - * The configuration options you can set for this module are in this section. - * Either change them in config.h or define them on the compiler command line. - * \{ - */ - -#if !defined(MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT) -#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT 86400 /*!< 1 day */ -#endif - -#if !defined(MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES) -#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /*!< Maximum entries in cache */ -#endif - -/* \} name SECTION: Module settings */ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct mbedtls_ssl_cache_context mbedtls_ssl_cache_context; -typedef struct mbedtls_ssl_cache_entry mbedtls_ssl_cache_entry; - -/** - * \brief This structure is used for storing cache entries - */ -struct mbedtls_ssl_cache_entry -{ -#if defined(MBEDTLS_HAVE_TIME) - mbedtls_time_t timestamp; /*!< entry timestamp */ -#endif - mbedtls_ssl_session session; /*!< entry session */ -#if defined(MBEDTLS_X509_CRT_PARSE_C) && \ - defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - mbedtls_x509_buf peer_cert; /*!< entry peer_cert */ -#endif - mbedtls_ssl_cache_entry *next; /*!< chain pointer */ -}; - -/** - * \brief Cache context - */ -struct mbedtls_ssl_cache_context -{ - mbedtls_ssl_cache_entry *chain; /*!< start of the chain */ - int timeout; /*!< cache entry timeout */ - int max_entries; /*!< maximum entries */ -#if defined(MBEDTLS_THREADING_C) - mbedtls_threading_mutex_t mutex; /*!< mutex */ -#endif -}; - -/** - * \brief Initialize an SSL cache context - * - * \param cache SSL cache context - */ -void mbedtls_ssl_cache_init( mbedtls_ssl_cache_context *cache ); - -/** - * \brief Cache get callback implementation - * (Thread-safe if MBEDTLS_THREADING_C is enabled) - * - * \param data SSL cache context - * \param session session to retrieve entry for - */ -int mbedtls_ssl_cache_get( void *data, mbedtls_ssl_session *session ); - -/** - * \brief Cache set callback implementation - * (Thread-safe if MBEDTLS_THREADING_C is enabled) - * - * \param data SSL cache context - * \param session session to store entry for - */ -int mbedtls_ssl_cache_set( void *data, const mbedtls_ssl_session *session ); - -#if defined(MBEDTLS_HAVE_TIME) -/** - * \brief Set the cache timeout - * (Default: MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT (1 day)) - * - * A timeout of 0 indicates no timeout. - * - * \param cache SSL cache context - * \param timeout cache entry timeout in seconds - */ -void mbedtls_ssl_cache_set_timeout( mbedtls_ssl_cache_context *cache, int timeout ); -#endif /* MBEDTLS_HAVE_TIME */ - -/** - * \brief Set the maximum number of cache entries - * (Default: MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES (50)) - * - * \param cache SSL cache context - * \param max cache entry maximum - */ -void mbedtls_ssl_cache_set_max_entries( mbedtls_ssl_cache_context *cache, int max ); - -/** - * \brief Free referenced items in a cache context and clear memory - * - * \param cache SSL cache context - */ -void mbedtls_ssl_cache_free( mbedtls_ssl_cache_context *cache ); - -#ifdef __cplusplus -} -#endif - -#endif /* ssl_cache.h */ diff --git a/include/mbedtls/ssl_ciphersuites.h b/include/mbedtls/ssl_ciphersuites.h deleted file mode 100644 index 712678330..000000000 --- a/include/mbedtls/ssl_ciphersuites.h +++ /dev/null @@ -1,558 +0,0 @@ -/** - * \file ssl_ciphersuites.h - * - * \brief SSL Ciphersuites for mbed TLS - */ -/* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -#ifndef MBEDTLS_SSL_CIPHERSUITES_H -#define MBEDTLS_SSL_CIPHERSUITES_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "pk.h" -#include "cipher.h" -#include "md.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Supported ciphersuites (Official IANA names) - */ -#define MBEDTLS_TLS_RSA_WITH_NULL_MD5 0x01 /**< Weak! */ -#define MBEDTLS_TLS_RSA_WITH_NULL_SHA 0x02 /**< Weak! */ - -#define MBEDTLS_TLS_RSA_WITH_RC4_128_MD5 0x04 -#define MBEDTLS_TLS_RSA_WITH_RC4_128_SHA 0x05 -#define MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA 0x09 /**< Weak! Not in TLS 1.2 */ - -#define MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA 0x0A - -#define MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA 0x15 /**< Weak! Not in TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA 0x16 - -#define MBEDTLS_TLS_PSK_WITH_NULL_SHA 0x2C /**< Weak! */ -#define MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA 0x2D /**< Weak! */ -#define MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA 0x2E /**< Weak! */ -#define MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA 0x2F - -#define MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA 0x33 -#define MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA 0x35 -#define MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA 0x39 - -#define MBEDTLS_TLS_RSA_WITH_NULL_SHA256 0x3B /**< Weak! */ -#define MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256 0x3C /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256 0x3D /**< TLS 1.2 */ - -#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA 0x41 -#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA 0x45 - -#define MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 0x67 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 0x6B /**< TLS 1.2 */ - -#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA 0x84 -#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA 0x88 - -#define MBEDTLS_TLS_PSK_WITH_RC4_128_SHA 0x8A -#define MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA 0x8B -#define MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA 0x8C -#define MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA 0x8D - -#define MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA 0x8E -#define MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA 0x8F -#define MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA 0x90 -#define MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA 0x91 - -#define MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA 0x92 -#define MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA 0x93 -#define MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA 0x94 -#define MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA 0x95 - -#define MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256 0x9C /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384 0x9D /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 0x9E /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 0x9F /**< TLS 1.2 */ - -#define MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256 0xA8 /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384 0xA9 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 0xAA /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 0xAB /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 0xAC /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 0xAD /**< TLS 1.2 */ - -#define MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256 0xAE -#define MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384 0xAF -#define MBEDTLS_TLS_PSK_WITH_NULL_SHA256 0xB0 /**< Weak! */ -#define MBEDTLS_TLS_PSK_WITH_NULL_SHA384 0xB1 /**< Weak! */ - -#define MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 0xB2 -#define MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 0xB3 -#define MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256 0xB4 /**< Weak! */ -#define MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384 0xB5 /**< Weak! */ - -#define MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 0xB6 -#define MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 0xB7 -#define MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256 0xB8 /**< Weak! */ -#define MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384 0xB9 /**< Weak! */ - -#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xBA /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xBE /**< TLS 1.2 */ - -#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 0xC0 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 0xC4 /**< TLS 1.2 */ - -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA 0xC001 /**< Weak! */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA 0xC002 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA 0xC003 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA 0xC004 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA 0xC005 /**< Not in SSL3! */ - -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA 0xC006 /**< Weak! */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA 0xC007 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA 0xC008 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0xC009 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0xC00A /**< Not in SSL3! */ - -#define MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA 0xC00B /**< Weak! */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA 0xC00C /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA 0xC00D /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA 0xC00E /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA 0xC00F /**< Not in SSL3! */ - -#define MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA 0xC010 /**< Weak! */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA 0xC011 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA 0xC012 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 0xC013 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 0xC014 /**< Not in SSL3! */ - -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 0xC023 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 0xC024 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 0xC025 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 0xC026 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 0xC027 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 0xC028 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 0xC029 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 0xC02A /**< TLS 1.2 */ - -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0xC02B /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 0xC02C /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 0xC02D /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 0xC02E /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0xC02F /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0xC030 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 0xC031 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 0xC032 /**< TLS 1.2 */ - -#define MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA 0xC033 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA 0xC034 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA 0xC035 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA 0xC036 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 0xC037 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 0xC038 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA 0xC039 /**< Weak! No SSL3! */ -#define MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256 0xC03A /**< Weak! No SSL3! */ -#define MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384 0xC03B /**< Weak! No SSL3! */ - -#define MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256 0xC03C /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384 0xC03D /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 0xC044 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 0xC045 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 0xC048 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 0xC049 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 0xC04A /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 0xC04B /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 0xC04C /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 0xC04D /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 0xC04E /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 0xC04F /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256 0xC050 /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384 0xC051 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256 0xC052 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384 0xC053 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 0xC05C /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 0xC05D /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 0xC05E /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 0xC05F /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 0xC060 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 0xC061 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 0xC062 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 0xC063 /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256 0xC064 /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384 0xC065 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 0xC066 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 0xC067 /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 0xC068 /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 0xC069 /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256 0xC06A /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384 0xC06B /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256 0xC06C /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384 0xC06D /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 0xC06E /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 0xC06F /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 0xC070 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 0xC071 /**< TLS 1.2 */ - -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 0xC072 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 0xC073 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 0xC074 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 0xC075 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xC076 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 0xC077 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xC078 /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 0xC079 /**< Not in SSL3! */ - -#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 0xC07A /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 0xC07B /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 0xC07C /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 0xC07D /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 0xC086 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 0xC087 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 0xC088 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 0xC089 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 0xC08A /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 0xC08B /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 0xC08C /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 0xC08D /**< TLS 1.2 */ - -#define MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 0xC08E /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 0xC08F /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 0xC090 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 0xC091 /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 0xC092 /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 0xC093 /**< TLS 1.2 */ - -#define MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC094 -#define MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC095 -#define MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC096 -#define MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC097 -#define MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC098 -#define MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC099 -#define MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC09A /**< Not in SSL3! */ -#define MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC09B /**< Not in SSL3! */ - -#define MBEDTLS_TLS_RSA_WITH_AES_128_CCM 0xC09C /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_WITH_AES_256_CCM 0xC09D /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM 0xC09E /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM 0xC09F /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8 0xC0A0 /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8 0xC0A1 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8 0xC0A2 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8 0xC0A3 /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_AES_128_CCM 0xC0A4 /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_AES_256_CCM 0xC0A5 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM 0xC0A6 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM 0xC0A7 /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8 0xC0A8 /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8 0xC0A9 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8 0xC0AA /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8 0xC0AB /**< TLS 1.2 */ -/* The last two are named with PSK_DHE in the RFC, which looks like a typo */ - -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM 0xC0AC /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM 0xC0AD /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 0xC0AE /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 0xC0AF /**< TLS 1.2 */ - -#define MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8 0xC0FF /**< experimental */ - -/* RFC 7905 */ -#define MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA8 /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA9 /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCCAA /**< TLS 1.2 */ -#define MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAB /**< TLS 1.2 */ -#define MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAC /**< TLS 1.2 */ -#define MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAD /**< TLS 1.2 */ -#define MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAE /**< TLS 1.2 */ - -/* Reminder: update mbedtls_ssl_premaster_secret when adding a new key exchange. - * Reminder: update MBEDTLS_KEY_EXCHANGE__xxx below - */ -typedef enum { - MBEDTLS_KEY_EXCHANGE_NONE = 0, - MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, - MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_KEY_EXCHANGE_ECJPAKE, -} mbedtls_key_exchange_type_t; - -/* Key exchanges using a certificate */ -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) -#define MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED -#endif - -/* Key exchanges allowing client certificate requests */ -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) -#define MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED -#endif - -/* Key exchanges involving server signature in ServerKeyExchange */ -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) -#define MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED -#endif - -/* Key exchanges using ECDH */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) -#define MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED -#endif - -/* Key exchanges that don't involve ephemeral keys */ -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED) -#define MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED -#endif - -/* Key exchanges that involve ephemeral keys */ -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -#define MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED -#endif - -/* Key exchanges using a PSK */ -#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) -#define MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED -#endif - -/* Key exchanges using DHE */ -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) -#define MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED -#endif - -/* Key exchanges using ECDHE */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) -#define MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED -#endif - -typedef struct mbedtls_ssl_ciphersuite_t mbedtls_ssl_ciphersuite_t; - -#define MBEDTLS_CIPHERSUITE_WEAK 0x01 /**< Weak ciphersuite flag */ -#define MBEDTLS_CIPHERSUITE_SHORT_TAG 0x02 /**< Short authentication tag, - eg for CCM_8 */ -#define MBEDTLS_CIPHERSUITE_NODTLS 0x04 /**< Can't be used with DTLS */ - -/** - * \brief This structure is used for storing ciphersuite information - */ -struct mbedtls_ssl_ciphersuite_t -{ - int id; - const char * name; - - mbedtls_cipher_type_t cipher; - mbedtls_md_type_t mac; - mbedtls_key_exchange_type_t key_exchange; - - int min_major_ver; - int min_minor_ver; - int max_major_ver; - int max_minor_ver; - - unsigned char flags; -}; - -const int *mbedtls_ssl_list_ciphersuites( void ); - -const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_string( const char *ciphersuite_name ); -const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_id( int ciphersuite_id ); - -#if defined(MBEDTLS_PK_C) -mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_pk_alg( const mbedtls_ssl_ciphersuite_t *info ); -mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_alg( const mbedtls_ssl_ciphersuite_t *info ); -#endif - -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->key_exchange ) - { - case MBEDTLS_KEY_EXCHANGE_DHE_RSA: - case MBEDTLS_KEY_EXCHANGE_DHE_PSK: - 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__SOME_NON_PFS__ENABLED) -static inline int mbedtls_ssl_ciphersuite_no_pfs( const mbedtls_ssl_ciphersuite_t *info ) -{ - switch( info->key_exchange ) - { - case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: - case MBEDTLS_KEY_EXCHANGE_RSA: - case MBEDTLS_KEY_EXCHANGE_PSK: - case MBEDTLS_KEY_EXCHANGE_RSA_PSK: - return( 1 ); - - default: - return( 0 ); - } -} -#endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED) -static inline int mbedtls_ssl_ciphersuite_uses_ecdh( const mbedtls_ssl_ciphersuite_t *info ) -{ - switch( info->key_exchange ) - { - case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: - return( 1 ); - - default: - return( 0 ); - } -} -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED */ - -static inline int mbedtls_ssl_ciphersuite_cert_req_allowed( const mbedtls_ssl_ciphersuite_t *info ) -{ - switch( info->key_exchange ) - { - case MBEDTLS_KEY_EXCHANGE_RSA: - case MBEDTLS_KEY_EXCHANGE_DHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: - 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->key_exchange ) - { - case MBEDTLS_KEY_EXCHANGE_RSA: - case MBEDTLS_KEY_EXCHANGE_RSA_PSK: - case MBEDTLS_KEY_EXCHANGE_DHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: - return( 1 ); - - default: - return( 0 ); - } -} - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED) -static inline int mbedtls_ssl_ciphersuite_uses_dhe( const mbedtls_ssl_ciphersuite_t *info ) -{ - switch( info->key_exchange ) - { - case MBEDTLS_KEY_EXCHANGE_DHE_RSA: - case MBEDTLS_KEY_EXCHANGE_DHE_PSK: - return( 1 ); - - default: - return( 0 ); - } -} -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED) */ - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED) -static inline int mbedtls_ssl_ciphersuite_uses_ecdhe( const mbedtls_ssl_ciphersuite_t *info ) -{ - switch( info->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->key_exchange ) - { - case MBEDTLS_KEY_EXCHANGE_DHE_RSA: - 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 */ - -#ifdef __cplusplus -} -#endif - -#endif /* ssl_ciphersuites.h */ diff --git a/include/mbedtls/ssl_cookie.h b/include/mbedtls/ssl_cookie.h deleted file mode 100644 index e34760ae8..000000000 --- a/include/mbedtls/ssl_cookie.h +++ /dev/null @@ -1,115 +0,0 @@ -/** - * \file ssl_cookie.h - * - * \brief DTLS cookie callbacks implementation - */ -/* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -#ifndef MBEDTLS_SSL_COOKIE_H -#define MBEDTLS_SSL_COOKIE_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "ssl.h" - -#if defined(MBEDTLS_THREADING_C) -#include "threading.h" -#endif - -/** - * \name SECTION: Module settings - * - * The configuration options you can set for this module are in this section. - * Either change them in config.h or define them on the compiler command line. - * \{ - */ -#ifndef MBEDTLS_SSL_COOKIE_TIMEOUT -#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */ -#endif - -/* \} name SECTION: Module settings */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Context for the default cookie functions. - */ -typedef struct mbedtls_ssl_cookie_ctx -{ - mbedtls_md_context_t hmac_ctx; /*!< context for the HMAC portion */ -#if !defined(MBEDTLS_HAVE_TIME) - unsigned long serial; /*!< serial number for expiration */ -#endif - unsigned long timeout; /*!< timeout delay, in seconds if HAVE_TIME, - or in number of tickets issued */ - -#if defined(MBEDTLS_THREADING_C) - mbedtls_threading_mutex_t mutex; -#endif -} mbedtls_ssl_cookie_ctx; - -/** - * \brief Initialize cookie context - */ -void mbedtls_ssl_cookie_init( mbedtls_ssl_cookie_ctx *ctx ); - -/** - * \brief Setup cookie context (generate keys) - */ -int mbedtls_ssl_cookie_setup( mbedtls_ssl_cookie_ctx *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); - -/** - * \brief Set expiration delay for cookies - * (Default MBEDTLS_SSL_COOKIE_TIMEOUT) - * - * \param ctx Cookie contex - * \param delay Delay, in seconds if HAVE_TIME, or in number of cookies - * issued in the meantime. - * 0 to disable expiration (NOT recommended) - */ -void mbedtls_ssl_cookie_set_timeout( mbedtls_ssl_cookie_ctx *ctx, unsigned long delay ); - -/** - * \brief Free cookie context - */ -void mbedtls_ssl_cookie_free( mbedtls_ssl_cookie_ctx *ctx ); - -/** - * \brief Generate cookie, see \c mbedtls_ssl_cookie_write_t - */ -mbedtls_ssl_cookie_write_t mbedtls_ssl_cookie_write; - -/** - * \brief Verify cookie, see \c mbedtls_ssl_cookie_write_t - */ -mbedtls_ssl_cookie_check_t mbedtls_ssl_cookie_check; - -#ifdef __cplusplus -} -#endif - -#endif /* ssl_cookie.h */ diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h deleted file mode 100644 index 5dde239df..000000000 --- a/include/mbedtls/ssl_internal.h +++ /dev/null @@ -1,819 +0,0 @@ -/** - * \file ssl_internal.h - * - * \brief Internal functions shared by the SSL modules - */ -/* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -#ifndef MBEDTLS_SSL_INTERNAL_H -#define MBEDTLS_SSL_INTERNAL_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "ssl.h" -#include "cipher.h" - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "psa/crypto.h" -#endif - -#if defined(MBEDTLS_MD5_C) -#include "md5.h" -#endif - -#if defined(MBEDTLS_SHA1_C) -#include "sha1.h" -#endif - -#if defined(MBEDTLS_SHA256_C) -#include "sha256.h" -#endif - -#if defined(MBEDTLS_SHA512_C) -#include "sha512.h" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -#include "ecjpake.h" -#endif - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "psa/crypto.h" -#include "psa_util.h" -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - -/* Determine minimum supported version */ -#define MBEDTLS_SSL_MIN_MAJOR_VERSION MBEDTLS_SSL_MAJOR_VERSION_3 - -#if defined(MBEDTLS_SSL_PROTO_SSL3) -#define MBEDTLS_SSL_MIN_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_0 -#else -#if defined(MBEDTLS_SSL_PROTO_TLS1) -#define MBEDTLS_SSL_MIN_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_1 -#else -#if defined(MBEDTLS_SSL_PROTO_TLS1_1) -#define MBEDTLS_SSL_MIN_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_2 -#else -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#define MBEDTLS_SSL_MIN_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_3 -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ -#endif /* MBEDTLS_SSL_PROTO_TLS1_1 */ -#endif /* MBEDTLS_SSL_PROTO_TLS1 */ -#endif /* MBEDTLS_SSL_PROTO_SSL3 */ - -#define MBEDTLS_SSL_MIN_VALID_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_1 -#define MBEDTLS_SSL_MIN_VALID_MAJOR_VERSION MBEDTLS_SSL_MAJOR_VERSION_3 - -/* Determine maximum supported version */ -#define MBEDTLS_SSL_MAX_MAJOR_VERSION MBEDTLS_SSL_MAJOR_VERSION_3 - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#define MBEDTLS_SSL_MAX_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_3 -#else -#if defined(MBEDTLS_SSL_PROTO_TLS1_1) -#define MBEDTLS_SSL_MAX_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_2 -#else -#if defined(MBEDTLS_SSL_PROTO_TLS1) -#define MBEDTLS_SSL_MAX_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_1 -#else -#if defined(MBEDTLS_SSL_PROTO_SSL3) -#define MBEDTLS_SSL_MAX_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_0 -#endif /* MBEDTLS_SSL_PROTO_SSL3 */ -#endif /* MBEDTLS_SSL_PROTO_TLS1 */ -#endif /* MBEDTLS_SSL_PROTO_TLS1_1 */ -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -/* Shorthand for restartable ECC */ -#if defined(MBEDTLS_ECP_RESTARTABLE) && \ - defined(MBEDTLS_SSL_CLI_C) && \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) -#define MBEDTLS_SSL__ECP_RESTARTABLE -#endif - -#define MBEDTLS_SSL_INITIAL_HANDSHAKE 0 -#define MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS 1 /* In progress */ -#define MBEDTLS_SSL_RENEGOTIATION_DONE 2 /* Done or aborted */ -#define MBEDTLS_SSL_RENEGOTIATION_PENDING 3 /* Requested (server only) */ - -/* - * DTLS retransmission states, see RFC 6347 4.2.4 - * - * The SENDING state is merged in PREPARING for initial sends, - * but is distinct for resends. - * - * Note: initial state is wrong for server, but is not used anyway. - */ -#define MBEDTLS_SSL_RETRANS_PREPARING 0 -#define MBEDTLS_SSL_RETRANS_SENDING 1 -#define MBEDTLS_SSL_RETRANS_WAITING 2 -#define MBEDTLS_SSL_RETRANS_FINISHED 3 - -/* - * Allow extra bytes for record, authentication and encryption overhead: - * counter (8) + header (5) + IV(16) + MAC (16-48) + padding (0-256) - * and allow for a maximum of 1024 of compression expansion if - * enabled. - */ -#if defined(MBEDTLS_ZLIB_SUPPORT) -#define MBEDTLS_SSL_COMPRESSION_ADD 1024 -#else -#define MBEDTLS_SSL_COMPRESSION_ADD 0 -#endif - -#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_MODE_CBC) -/* Ciphersuites using HMAC */ -#if defined(MBEDTLS_SHA512_C) -#define MBEDTLS_SSL_MAC_ADD 48 /* SHA-384 used for HMAC */ -#elif defined(MBEDTLS_SHA256_C) -#define MBEDTLS_SSL_MAC_ADD 32 /* SHA-256 used for HMAC */ -#else -#define MBEDTLS_SSL_MAC_ADD 20 /* SHA-1 used for HMAC */ -#endif -#else -/* AEAD ciphersuites: GCM and CCM use a 128 bits tag */ -#define MBEDTLS_SSL_MAC_ADD 16 -#endif - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#define MBEDTLS_SSL_PADDING_ADD 256 -#else -#define MBEDTLS_SSL_PADDING_ADD 0 -#endif - -#define MBEDTLS_SSL_PAYLOAD_OVERHEAD ( MBEDTLS_SSL_COMPRESSION_ADD + \ - MBEDTLS_MAX_IV_LENGTH + \ - MBEDTLS_SSL_MAC_ADD + \ - MBEDTLS_SSL_PADDING_ADD \ - ) - -#define MBEDTLS_SSL_IN_PAYLOAD_LEN ( MBEDTLS_SSL_PAYLOAD_OVERHEAD + \ - ( MBEDTLS_SSL_IN_CONTENT_LEN ) ) - -#define MBEDTLS_SSL_OUT_PAYLOAD_LEN ( MBEDTLS_SSL_PAYLOAD_OVERHEAD + \ - ( MBEDTLS_SSL_OUT_CONTENT_LEN ) ) - -/* The maximum number of buffered handshake messages. */ -#define MBEDTLS_SSL_MAX_BUFFERED_HS 4 - -/* Maximum length we can advertise as our max content length for - RFC 6066 max_fragment_length extension negotiation purposes - (the lesser of both sizes, if they are unequal.) - */ -#define MBEDTLS_TLS_EXT_ADV_CONTENT_LEN ( \ - (MBEDTLS_SSL_IN_CONTENT_LEN > MBEDTLS_SSL_OUT_CONTENT_LEN) \ - ? ( MBEDTLS_SSL_OUT_CONTENT_LEN ) \ - : ( MBEDTLS_SSL_IN_CONTENT_LEN ) \ - ) - -/* - * Check that we obey the standard's message size bounds - */ - -#if MBEDTLS_SSL_MAX_CONTENT_LEN > 16384 -#error "Bad configuration - record content too large." -#endif - -#if MBEDTLS_SSL_IN_CONTENT_LEN > MBEDTLS_SSL_MAX_CONTENT_LEN -#error "Bad configuration - incoming record content should not be larger than MBEDTLS_SSL_MAX_CONTENT_LEN." -#endif - -#if MBEDTLS_SSL_OUT_CONTENT_LEN > MBEDTLS_SSL_MAX_CONTENT_LEN -#error "Bad configuration - outgoing record content should not be larger than MBEDTLS_SSL_MAX_CONTENT_LEN." -#endif - -#if MBEDTLS_SSL_IN_PAYLOAD_LEN > MBEDTLS_SSL_MAX_CONTENT_LEN + 2048 -#error "Bad configuration - incoming protected record payload too large." -#endif - -#if MBEDTLS_SSL_OUT_PAYLOAD_LEN > MBEDTLS_SSL_MAX_CONTENT_LEN + 2048 -#error "Bad configuration - outgoing protected record payload too large." -#endif - -/* Calculate buffer sizes */ - -/* Note: Even though the TLS record header is only 5 bytes - long, we're internally using 8 bytes to store the - implicit sequence number. */ -#define MBEDTLS_SSL_HEADER_LEN 13 - -#define MBEDTLS_SSL_IN_BUFFER_LEN \ - ( ( MBEDTLS_SSL_HEADER_LEN ) + ( MBEDTLS_SSL_IN_PAYLOAD_LEN ) ) - -#define MBEDTLS_SSL_OUT_BUFFER_LEN \ - ( ( MBEDTLS_SSL_HEADER_LEN ) + ( MBEDTLS_SSL_OUT_PAYLOAD_LEN ) ) - -#ifdef MBEDTLS_ZLIB_SUPPORT -/* Compression buffer holds both IN and OUT buffers, so should be size of the larger */ -#define MBEDTLS_SSL_COMPRESS_BUFFER_LEN ( \ - ( MBEDTLS_SSL_IN_BUFFER_LEN > MBEDTLS_SSL_OUT_BUFFER_LEN ) \ - ? MBEDTLS_SSL_IN_BUFFER_LEN \ - : MBEDTLS_SSL_OUT_BUFFER_LEN \ - ) -#endif - -/* - * TLS extension flags (for extensions with outgoing ServerHello content - * that need it (e.g. for RENEGOTIATION_INFO the server already knows because - * of state of the renegotiation flag, so no indicator is required) - */ -#define MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT (1 << 0) -#define MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK (1 << 1) - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) -/* - * Abstraction for a grid of allowed signature-hash-algorithm pairs. - */ -struct mbedtls_ssl_sig_hash_set_t -{ - /* At the moment, we only need to remember a single suitable - * hash algorithm per signature algorithm. As long as that's - * the case - and we don't need a general lookup function - - * we can implement the sig-hash-set as a map from signatures - * to hash algorithms. */ - mbedtls_md_type_t rsa; - mbedtls_md_type_t ecdsa; -}; -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && - MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ - -/* - * This structure contains the parameters only needed during handshake. - */ -struct mbedtls_ssl_handshake_params -{ - /* - * Handshake specific crypto variables - */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) - mbedtls_ssl_sig_hash_set_t hash_algs; /*!< Set of suitable sig-hash pairs */ -#endif -#if defined(MBEDTLS_DHM_C) - mbedtls_dhm_context dhm_ctx; /*!< DHM key exchange */ -#endif -#if defined(MBEDTLS_ECDH_C) - mbedtls_ecdh_context ecdh_ctx; /*!< ECDH key exchange */ - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_ecc_curve_t ecdh_psa_curve; - psa_key_handle_t ecdh_psa_privkey; - unsigned char ecdh_psa_peerkey[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH]; - size_t ecdh_psa_peerkey_len; -#endif /* MBEDTLS_USE_PSA_CRYPTO */ -#endif /* MBEDTLS_ECDH_C */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - mbedtls_ecjpake_context ecjpake_ctx; /*!< EC J-PAKE key exchange */ -#if defined(MBEDTLS_SSL_CLI_C) - unsigned char *ecjpake_cache; /*!< Cache for ClientHello ext */ - size_t ecjpake_cache_len; /*!< Length of cached data */ -#endif -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - const mbedtls_ecp_curve_info **curves; /*!< Supported elliptic curves */ -#endif -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_key_handle_t psk_opaque; /*!< Opaque PSK from the callback */ -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - unsigned char *psk; /*!< PSK from the callback */ - size_t psk_len; /*!< Length of PSK from callback */ -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ -#if defined(MBEDTLS_X509_CRT_PARSE_C) - mbedtls_ssl_key_cert *key_cert; /*!< chosen key/cert pair (server) */ -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - int sni_authmode; /*!< authmode from SNI callback */ - mbedtls_ssl_key_cert *sni_key_cert; /*!< key/cert list from SNI */ - mbedtls_x509_crt *sni_ca_chain; /*!< trusted CAs from SNI callback */ - mbedtls_x509_crl *sni_ca_crl; /*!< trusted CAs CRLs from SNI */ -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - int ecrs_enabled; /*!< Handshake supports EC restart? */ - mbedtls_x509_crt_restart_ctx ecrs_ctx; /*!< restart context */ - enum { /* this complements ssl->state with info on intra-state operations */ - ssl_ecrs_none = 0, /*!< nothing going on (yet) */ - ssl_ecrs_crt_verify, /*!< Certificate: crt_verify() */ - ssl_ecrs_ske_start_processing, /*!< ServerKeyExchange: pk_verify() */ - ssl_ecrs_cke_ecdh_calc_secret, /*!< ClientKeyExchange: ECDH step 2 */ - ssl_ecrs_crt_vrfy_sign, /*!< CertificateVerify: pk_sign() */ - } ecrs_state; /*!< current (or last) operation */ - mbedtls_x509_crt *ecrs_peer_cert; /*!< The peer's CRT chain. */ - size_t ecrs_n; /*!< place for saving a length */ -#endif -#if defined(MBEDTLS_X509_CRT_PARSE_C) && \ - !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - mbedtls_pk_context peer_pubkey; /*!< The public key from the peer. */ -#endif /* MBEDTLS_X509_CRT_PARSE_C && !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - unsigned int out_msg_seq; /*!< Outgoing handshake sequence number */ - unsigned int in_msg_seq; /*!< Incoming handshake sequence number */ - - unsigned char *verify_cookie; /*!< Cli: HelloVerifyRequest cookie - Srv: unused */ - unsigned char verify_cookie_len; /*!< Cli: cookie length - Srv: flag for sending a cookie */ - - uint32_t retransmit_timeout; /*!< Current value of timeout */ - unsigned char retransmit_state; /*!< Retransmission state */ - mbedtls_ssl_flight_item *flight; /*!< Current outgoing flight */ - mbedtls_ssl_flight_item *cur_msg; /*!< Current message in flight */ - unsigned char *cur_msg_p; /*!< Position in current message */ - unsigned int in_flight_start_seq; /*!< Minimum message sequence in the - flight being received */ - mbedtls_ssl_transform *alt_transform_out; /*!< Alternative transform for - resending messages */ - unsigned char alt_out_ctr[8]; /*!< Alternative record epoch/counter - for resending messages */ - - struct - { - size_t total_bytes_buffered; /*!< Cumulative size of heap allocated - * buffers used for message buffering. */ - - uint8_t seen_ccs; /*!< Indicates if a CCS message has - * been seen in the current flight. */ - - struct mbedtls_ssl_hs_buffer - { - unsigned is_valid : 1; - unsigned is_fragmented : 1; - unsigned is_complete : 1; - unsigned char *data; - size_t data_len; - } hs[MBEDTLS_SSL_MAX_BUFFERED_HS]; - - struct - { - unsigned char *data; - size_t len; - unsigned epoch; - } future_record; - - } buffering; - - uint16_t mtu; /*!< Handshake mtu, used to fragment outgoing messages */ -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - /* - * Checksum contexts - */ -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) - mbedtls_md5_context fin_md5; - mbedtls_sha1_context fin_sha1; -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_SHA256_C) -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_hash_operation_t fin_sha256_psa; -#else - mbedtls_sha256_context fin_sha256; -#endif -#endif -#if defined(MBEDTLS_SHA512_C) -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_hash_operation_t fin_sha384_psa; -#else - mbedtls_sha512_context fin_sha512; -#endif -#endif -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - - void (*update_checksum)(mbedtls_ssl_context *, const unsigned char *, size_t); - void (*calc_verify)(mbedtls_ssl_context *, unsigned char *); - void (*calc_finished)(mbedtls_ssl_context *, unsigned char *, int); - int (*tls_prf)(const unsigned char *, size_t, const char *, - const unsigned char *, size_t, - unsigned char *, size_t); - - size_t pmslen; /*!< premaster length */ - - unsigned char randbytes[64]; /*!< random bytes */ - unsigned char premaster[MBEDTLS_PREMASTER_SIZE]; - /*!< premaster secret */ - - int resume; /*!< session resume indicator*/ - int max_major_ver; /*!< max. major version client*/ - int max_minor_ver; /*!< max. minor version client*/ - int cli_exts; /*!< client extension presence*/ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - int new_session_ticket; /*!< use NewSessionTicket? */ -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - int extended_ms; /*!< use Extended Master Secret? */ -#endif - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - unsigned int async_in_progress : 1; /*!< an asynchronous operation is in progress */ -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - /** Asynchronous operation context. This field is meant for use by the - * asynchronous operation callbacks (mbedtls_ssl_config::f_async_sign_start, - * mbedtls_ssl_config::f_async_decrypt_start, - * mbedtls_ssl_config::f_async_resume, mbedtls_ssl_config::f_async_cancel). - * The library does not use it internally. */ - void *user_async_ctx; -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ -}; - -typedef struct mbedtls_ssl_hs_buffer mbedtls_ssl_hs_buffer; - -/* - * This structure contains a full set of runtime transform parameters - * either in negotiation or active. - */ -struct mbedtls_ssl_transform -{ - /* - * Session specific crypto layer - */ - const mbedtls_ssl_ciphersuite_t *ciphersuite_info; - /*!< Chosen cipersuite_info */ - unsigned int keylen; /*!< symmetric key length (bytes) */ - size_t minlen; /*!< min. ciphertext length */ - size_t ivlen; /*!< IV length */ - size_t fixed_ivlen; /*!< Fixed part of IV (AEAD) */ - size_t maclen; /*!< MAC length */ - - unsigned char iv_enc[16]; /*!< IV (encryption) */ - unsigned char iv_dec[16]; /*!< IV (decryption) */ - -#if defined(MBEDTLS_SSL_PROTO_SSL3) - /* Needed only for SSL v3.0 secret */ - unsigned char mac_enc[20]; /*!< SSL v3.0 secret (enc) */ - unsigned char mac_dec[20]; /*!< SSL v3.0 secret (dec) */ -#endif /* MBEDTLS_SSL_PROTO_SSL3 */ - - mbedtls_md_context_t md_ctx_enc; /*!< MAC (encryption) */ - mbedtls_md_context_t md_ctx_dec; /*!< MAC (decryption) */ - - mbedtls_cipher_context_t cipher_ctx_enc; /*!< encryption context */ - mbedtls_cipher_context_t cipher_ctx_dec; /*!< decryption context */ - - /* - * Session specific compression layer - */ -#if defined(MBEDTLS_ZLIB_SUPPORT) - z_stream ctx_deflate; /*!< compression context */ - z_stream ctx_inflate; /*!< decompression context */ -#endif -}; - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -/* - * List of certificate + private key pairs - */ -struct mbedtls_ssl_key_cert -{ - mbedtls_x509_crt *cert; /*!< cert */ - mbedtls_pk_context *key; /*!< private key */ - mbedtls_ssl_key_cert *next; /*!< next key/cert pair */ -}; -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) -/* - * List of handshake messages kept around for resending - */ -struct mbedtls_ssl_flight_item -{ - unsigned char *p; /*!< message, including handshake headers */ - size_t len; /*!< length of p */ - unsigned char type; /*!< type of the message: handshake or CCS */ - mbedtls_ssl_flight_item *next; /*!< next handshake message(s) */ -}; -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) - -/* Find an entry in a signature-hash set matching a given hash algorithm. */ -mbedtls_md_type_t mbedtls_ssl_sig_hash_set_find( mbedtls_ssl_sig_hash_set_t *set, - mbedtls_pk_type_t sig_alg ); -/* Add a signature-hash-pair to a signature-hash set */ -void mbedtls_ssl_sig_hash_set_add( mbedtls_ssl_sig_hash_set_t *set, - mbedtls_pk_type_t sig_alg, - mbedtls_md_type_t md_alg ); -/* Allow exactly one hash algorithm for each signature. */ -void mbedtls_ssl_sig_hash_set_const_hash( mbedtls_ssl_sig_hash_set_t *set, - mbedtls_md_type_t md_alg ); - -/* Setup an empty signature-hash set */ -static inline void mbedtls_ssl_sig_hash_set_init( mbedtls_ssl_sig_hash_set_t *set ) -{ - mbedtls_ssl_sig_hash_set_const_hash( set, MBEDTLS_MD_NONE ); -} - -#endif /* MBEDTLS_SSL_PROTO_TLS1_2) && - MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ - -/** - * \brief Free referenced items in an SSL transform context and clear - * memory - * - * \param transform SSL transform context - */ -void mbedtls_ssl_transform_free( mbedtls_ssl_transform *transform ); - -/** - * \brief Free referenced items in an SSL handshake context and clear - * memory - * - * \param ssl SSL context - */ -void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl ); - -int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl ); -int mbedtls_ssl_handshake_server_step( mbedtls_ssl_context *ssl ); -void mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl ); - -int mbedtls_ssl_send_fatal_handshake_failure( mbedtls_ssl_context *ssl ); - -void mbedtls_ssl_reset_checksum( mbedtls_ssl_context *ssl ); -int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ); - -int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl ); -int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl ); -void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl ); - -/** - * \brief Update record layer - * - * This function roughly separates the implementation - * of the logic of (D)TLS from the implementation - * of the secure transport. - * - * \param ssl The SSL context to use. - * \param update_hs_digest This indicates if the handshake digest - * should be automatically updated in case - * a handshake message is found. - * - * \return 0 or non-zero error code. - * - * \note A clarification on what is called 'record layer' here - * is in order, as many sensible definitions are possible: - * - * The record layer takes as input an untrusted underlying - * transport (stream or datagram) and transforms it into - * a serially multiplexed, secure transport, which - * conceptually provides the following: - * - * (1) Three datagram based, content-agnostic transports - * for handshake, alert and CCS messages. - * (2) One stream- or datagram-based transport - * for application data. - * (3) Functionality for changing the underlying transform - * securing the contents. - * - * The interface to this functionality is given as follows: - * - * a Updating - * [Currently implemented by mbedtls_ssl_read_record] - * - * Check if and on which of the four 'ports' data is pending: - * Nothing, a controlling datagram of type (1), or application - * data (2). In any case data is present, internal buffers - * provide access to the data for the user to process it. - * Consumption of type (1) datagrams is done automatically - * on the next update, invalidating that the internal buffers - * for previous datagrams, while consumption of application - * data (2) is user-controlled. - * - * b Reading of application data - * [Currently manual adaption of ssl->in_offt pointer] - * - * As mentioned in the last paragraph, consumption of data - * is different from the automatic consumption of control - * datagrams (1) because application data is treated as a stream. - * - * c Tracking availability of application data - * [Currently manually through decreasing ssl->in_msglen] - * - * For efficiency and to retain datagram semantics for - * application data in case of DTLS, the record layer - * provides functionality for checking how much application - * data is still available in the internal buffer. - * - * d Changing the transformation securing the communication. - * - * Given an opaque implementation of the record layer in the - * above sense, it should be possible to implement the logic - * of (D)TLS on top of it without the need to know anything - * about the record layer's internals. This is done e.g. - * in all the handshake handling functions, and in the - * application data reading function mbedtls_ssl_read. - * - * \note The above tries to give a conceptual picture of the - * record layer, but the current implementation deviates - * from it in some places. For example, our implementation of - * the update functionality through mbedtls_ssl_read_record - * discards datagrams depending on the current state, which - * wouldn't fall under the record layer's responsibility - * following the above definition. - * - */ -int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl, - unsigned update_hs_digest ); -int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ); - -int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl ); -int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush ); -int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl ); - -int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ); -int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl ); - -int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl ); -int mbedtls_ssl_write_change_cipher_spec( mbedtls_ssl_context *ssl ); - -int mbedtls_ssl_parse_finished( mbedtls_ssl_context *ssl ); -int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl ); - -void mbedtls_ssl_optimize_checksum( mbedtls_ssl_context *ssl, - const mbedtls_ssl_ciphersuite_t *ciphersuite_info ); - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) -int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exchange_type_t key_ex ); -#endif - -#if defined(MBEDTLS_PK_C) -unsigned char mbedtls_ssl_sig_from_pk( mbedtls_pk_context *pk ); -unsigned char mbedtls_ssl_sig_from_pk_alg( mbedtls_pk_type_t type ); -mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig( unsigned char sig ); -#endif - -mbedtls_md_type_t mbedtls_ssl_md_alg_from_hash( unsigned char hash ); -unsigned char mbedtls_ssl_hash_from_md_alg( int md ); -int mbedtls_ssl_set_calc_verify_md( mbedtls_ssl_context *ssl, int md ); - -#if defined(MBEDTLS_ECP_C) -int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id ); -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) -int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl, - mbedtls_md_type_t md ); -#endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -static inline mbedtls_pk_context *mbedtls_ssl_own_key( mbedtls_ssl_context *ssl ) -{ - mbedtls_ssl_key_cert *key_cert; - - if( ssl->handshake != NULL && ssl->handshake->key_cert != NULL ) - key_cert = ssl->handshake->key_cert; - else - key_cert = ssl->conf->key_cert; - - return( key_cert == NULL ? NULL : key_cert->key ); -} - -static inline mbedtls_x509_crt *mbedtls_ssl_own_cert( mbedtls_ssl_context *ssl ) -{ - mbedtls_ssl_key_cert *key_cert; - - if( ssl->handshake != NULL && ssl->handshake->key_cert != NULL ) - key_cert = ssl->handshake->key_cert; - else - key_cert = ssl->conf->key_cert; - - return( key_cert == NULL ? NULL : key_cert->cert ); -} - -/* - * Check usage of a certificate wrt extensions: - * keyUsage, extendedKeyUsage (later), and nSCertType (later). - * - * Warning: cert_endpoint is the endpoint of the cert (ie, of our peer when we - * check a cert we received from them)! - * - * Return 0 if everything is OK, -1 if not. - */ -int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert, - const mbedtls_ssl_ciphersuite_t *ciphersuite, - int cert_endpoint, - uint32_t *flags ); -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -void mbedtls_ssl_write_version( int major, int minor, int transport, - unsigned char ver[2] ); -void mbedtls_ssl_read_version( int *major, int *minor, int transport, - const unsigned char ver[2] ); - -static inline size_t mbedtls_ssl_hdr_len( const mbedtls_ssl_context *ssl ) -{ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - return( 13 ); -#else - ((void) ssl); -#endif - return( 5 ); -} - -static inline size_t mbedtls_ssl_hs_hdr_len( const mbedtls_ssl_context *ssl ) -{ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - return( 12 ); -#else - ((void) ssl); -#endif - return( 4 ); -} - -#if defined(MBEDTLS_SSL_PROTO_DTLS) -void mbedtls_ssl_send_flight_completed( mbedtls_ssl_context *ssl ); -void mbedtls_ssl_recv_flight_completed( mbedtls_ssl_context *ssl ); -int mbedtls_ssl_resend( mbedtls_ssl_context *ssl ); -int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl ); -#endif - -/* Visible for testing purposes only */ -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) -int mbedtls_ssl_dtls_replay_check( mbedtls_ssl_context *ssl ); -void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl ); -#endif - -int mbedtls_ssl_session_copy( mbedtls_ssl_session *dst, - const mbedtls_ssl_session *src ); - -/* constant-time buffer comparison */ -static inline int mbedtls_ssl_safer_memcmp( const void *a, const void *b, size_t n ) -{ - size_t i; - volatile const unsigned char *A = (volatile const unsigned char *) a; - volatile const unsigned char *B = (volatile const unsigned char *) b; - volatile unsigned char diff = 0; - - for( i = 0; i < n; i++ ) - { - /* Read volatile data in order before computing diff. - * This avoids IAR compiler warning: - * 'the order of volatile accesses is undefined ..' */ - unsigned char x = A[i], y = B[i]; - diff |= x ^ y; - } - - return( diff ); -} - -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) -int mbedtls_ssl_get_key_exchange_md_ssl_tls( mbedtls_ssl_context *ssl, - unsigned char *output, - unsigned char *data, size_t data_len ); -#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \ - MBEDTLS_SSL_PROTO_TLS1_1 */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) -/* The hash buffer must have at least MBEDTLS_MD_MAX_SIZE bytes of length. */ -int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl, - unsigned char *hash, size_t *hashlen, - unsigned char *data, size_t data_len, - mbedtls_md_type_t md_alg ); -#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ - MBEDTLS_SSL_PROTO_TLS1_2 */ - -#ifdef __cplusplus -} -#endif - -#endif /* ssl_internal.h */ diff --git a/include/mbedtls/ssl_ticket.h b/include/mbedtls/ssl_ticket.h deleted file mode 100644 index 774a007a9..000000000 --- a/include/mbedtls/ssl_ticket.h +++ /dev/null @@ -1,142 +0,0 @@ -/** - * \file ssl_ticket.h - * - * \brief TLS server ticket callbacks implementation - */ -/* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -#ifndef MBEDTLS_SSL_TICKET_H -#define MBEDTLS_SSL_TICKET_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -/* - * This implementation of the session ticket callbacks includes key - * management, rotating the keys periodically in order to preserve forward - * secrecy, when MBEDTLS_HAVE_TIME is defined. - */ - -#include "ssl.h" -#include "cipher.h" - -#if defined(MBEDTLS_THREADING_C) -#include "threading.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Information for session ticket protection - */ -typedef struct mbedtls_ssl_ticket_key -{ - unsigned char name[4]; /*!< random key identifier */ - uint32_t generation_time; /*!< key generation timestamp (seconds) */ - mbedtls_cipher_context_t ctx; /*!< context for auth enc/decryption */ -} -mbedtls_ssl_ticket_key; - -/** - * \brief Context for session ticket handling functions - */ -typedef struct mbedtls_ssl_ticket_context -{ - mbedtls_ssl_ticket_key keys[2]; /*!< ticket protection keys */ - unsigned char active; /*!< index of the currently active key */ - - uint32_t ticket_lifetime; /*!< lifetime of tickets in seconds */ - - /** Callback for getting (pseudo-)random numbers */ - int (*f_rng)(void *, unsigned char *, size_t); - void *p_rng; /*!< context for the RNG function */ - -#if defined(MBEDTLS_THREADING_C) - mbedtls_threading_mutex_t mutex; -#endif -} -mbedtls_ssl_ticket_context; - -/** - * \brief Initialize a ticket context. - * (Just make it ready for mbedtls_ssl_ticket_setup() - * or mbedtls_ssl_ticket_free().) - * - * \param ctx Context to be initialized - */ -void mbedtls_ssl_ticket_init( mbedtls_ssl_ticket_context *ctx ); - -/** - * \brief Prepare context to be actually used - * - * \param ctx Context to be set up - * \param f_rng RNG callback function - * \param p_rng RNG callback context - * \param cipher AEAD cipher to use for ticket protection. - * Recommended value: MBEDTLS_CIPHER_AES_256_GCM. - * \param lifetime Tickets lifetime in seconds - * Recommended value: 86400 (one day). - * - * \note It is highly recommended to select a cipher that is at - * least as strong as the the strongest ciphersuite - * supported. Usually that means a 256-bit key. - * - * \note The lifetime of the keys is twice the lifetime of tickets. - * It is recommended to pick a reasonnable lifetime so as not - * to negate the benefits of forward secrecy. - * - * \return 0 if successful, - * or a specific MBEDTLS_ERR_XXX error code - */ -int mbedtls_ssl_ticket_setup( mbedtls_ssl_ticket_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - mbedtls_cipher_type_t cipher, - uint32_t lifetime ); - -/** - * \brief Implementation of the ticket write callback - * - * \note See \c mbedtls_ssl_ticket_write_t for description - */ -mbedtls_ssl_ticket_write_t mbedtls_ssl_ticket_write; - -/** - * \brief Implementation of the ticket parse callback - * - * \note See \c mbedtls_ssl_ticket_parse_t for description - */ -mbedtls_ssl_ticket_parse_t mbedtls_ssl_ticket_parse; - -/** - * \brief Free a context's content and zeroize it. - * - * \param ctx Context to be cleaned up - */ -void mbedtls_ssl_ticket_free( mbedtls_ssl_ticket_context *ctx ); - -#ifdef __cplusplus -} -#endif - -#endif /* ssl_ticket.h */ diff --git a/include/mbedtls/x509.h b/include/mbedtls/x509.h deleted file mode 100644 index b63e864e3..000000000 --- a/include/mbedtls/x509.h +++ /dev/null @@ -1,339 +0,0 @@ -/** - * \file x509.h - * - * \brief X.509 generic defines and structures - */ -/* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -#ifndef MBEDTLS_X509_H -#define MBEDTLS_X509_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "asn1.h" -#include "pk.h" - -#if defined(MBEDTLS_RSA_C) -#include "rsa.h" -#endif - -/** - * \addtogroup x509_module - * \{ - */ - -#if !defined(MBEDTLS_X509_MAX_INTERMEDIATE_CA) -/** - * Maximum number of intermediate CAs in a verification chain. - * That is, maximum length of the chain, excluding the end-entity certificate - * and the trusted root certificate. - * - * Set this to a low value to prevent an adversary from making you waste - * resources verifying an overlong certificate chain. - */ -#define MBEDTLS_X509_MAX_INTERMEDIATE_CA 8 -#endif - -/** - * \name X509 Error codes - * \{ - */ -#define MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE -0x2080 /**< Unavailable feature, e.g. RSA hashing/encryption combination. */ -#define MBEDTLS_ERR_X509_UNKNOWN_OID -0x2100 /**< Requested OID is unknown. */ -#define MBEDTLS_ERR_X509_INVALID_FORMAT -0x2180 /**< The CRT/CRL/CSR format is invalid, e.g. different type expected. */ -#define MBEDTLS_ERR_X509_INVALID_VERSION -0x2200 /**< The CRT/CRL/CSR version element is invalid. */ -#define MBEDTLS_ERR_X509_INVALID_SERIAL -0x2280 /**< The serial tag or value is invalid. */ -#define MBEDTLS_ERR_X509_INVALID_ALG -0x2300 /**< The algorithm tag or value is invalid. */ -#define MBEDTLS_ERR_X509_INVALID_NAME -0x2380 /**< The name tag or value is invalid. */ -#define MBEDTLS_ERR_X509_INVALID_DATE -0x2400 /**< The date tag or value is invalid. */ -#define MBEDTLS_ERR_X509_INVALID_SIGNATURE -0x2480 /**< The signature tag or value invalid. */ -#define MBEDTLS_ERR_X509_INVALID_EXTENSIONS -0x2500 /**< The extension tag or value is invalid. */ -#define MBEDTLS_ERR_X509_UNKNOWN_VERSION -0x2580 /**< CRT/CRL/CSR has an unsupported version number. */ -#define MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG -0x2600 /**< Signature algorithm (oid) is unsupported. */ -#define MBEDTLS_ERR_X509_SIG_MISMATCH -0x2680 /**< Signature algorithms do not match. (see \c ::mbedtls_x509_crt sig_oid) */ -#define MBEDTLS_ERR_X509_CERT_VERIFY_FAILED -0x2700 /**< Certificate verification failed, e.g. CRL, CA or signature check failed. */ -#define MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT -0x2780 /**< Format not recognized as DER or PEM. */ -#define MBEDTLS_ERR_X509_BAD_INPUT_DATA -0x2800 /**< Input invalid. */ -#define MBEDTLS_ERR_X509_ALLOC_FAILED -0x2880 /**< Allocation of memory failed. */ -#define MBEDTLS_ERR_X509_FILE_IO_ERROR -0x2900 /**< Read/write of file failed. */ -#define MBEDTLS_ERR_X509_BUFFER_TOO_SMALL -0x2980 /**< Destination buffer is too small. */ -#define MBEDTLS_ERR_X509_FATAL_ERROR -0x3000 /**< A fatal error occurred, eg the chain is too long or the vrfy callback failed. */ -/* \} name */ - -/** - * \name X509 Verify codes - * \{ - */ -/* Reminder: update x509_crt_verify_strings[] in library/x509_crt.c */ -#define MBEDTLS_X509_BADCERT_EXPIRED 0x01 /**< The certificate validity has expired. */ -#define MBEDTLS_X509_BADCERT_REVOKED 0x02 /**< The certificate has been revoked (is on a CRL). */ -#define MBEDTLS_X509_BADCERT_CN_MISMATCH 0x04 /**< The certificate Common Name (CN) does not match with the expected CN. */ -#define MBEDTLS_X509_BADCERT_NOT_TRUSTED 0x08 /**< The certificate is not correctly signed by the trusted CA. */ -#define MBEDTLS_X509_BADCRL_NOT_TRUSTED 0x10 /**< The CRL is not correctly signed by the trusted CA. */ -#define MBEDTLS_X509_BADCRL_EXPIRED 0x20 /**< The CRL is expired. */ -#define MBEDTLS_X509_BADCERT_MISSING 0x40 /**< Certificate was missing. */ -#define MBEDTLS_X509_BADCERT_SKIP_VERIFY 0x80 /**< Certificate verification was skipped. */ -#define MBEDTLS_X509_BADCERT_OTHER 0x0100 /**< Other reason (can be used by verify callback) */ -#define MBEDTLS_X509_BADCERT_FUTURE 0x0200 /**< The certificate validity starts in the future. */ -#define MBEDTLS_X509_BADCRL_FUTURE 0x0400 /**< The CRL is from the future */ -#define MBEDTLS_X509_BADCERT_KEY_USAGE 0x0800 /**< Usage does not match the keyUsage extension. */ -#define MBEDTLS_X509_BADCERT_EXT_KEY_USAGE 0x1000 /**< Usage does not match the extendedKeyUsage extension. */ -#define MBEDTLS_X509_BADCERT_NS_CERT_TYPE 0x2000 /**< Usage does not match the nsCertType extension. */ -#define MBEDTLS_X509_BADCERT_BAD_MD 0x4000 /**< The certificate is signed with an unacceptable hash. */ -#define MBEDTLS_X509_BADCERT_BAD_PK 0x8000 /**< The certificate is signed with an unacceptable PK alg (eg RSA vs ECDSA). */ -#define MBEDTLS_X509_BADCERT_BAD_KEY 0x010000 /**< The certificate is signed with an unacceptable key (eg bad curve, RSA too short). */ -#define MBEDTLS_X509_BADCRL_BAD_MD 0x020000 /**< The CRL is signed with an unacceptable hash. */ -#define MBEDTLS_X509_BADCRL_BAD_PK 0x040000 /**< The CRL is signed with an unacceptable PK alg (eg RSA vs ECDSA). */ -#define MBEDTLS_X509_BADCRL_BAD_KEY 0x080000 /**< The CRL is signed with an unacceptable key (eg bad curve, RSA too short). */ - -/* \} name */ -/* \} addtogroup x509_module */ - -/* - * X.509 v3 Key Usage Extension flags - * Reminder: update x509_info_key_usage() when adding new flags. - */ -#define MBEDTLS_X509_KU_DIGITAL_SIGNATURE (0x80) /* bit 0 */ -#define MBEDTLS_X509_KU_NON_REPUDIATION (0x40) /* bit 1 */ -#define MBEDTLS_X509_KU_KEY_ENCIPHERMENT (0x20) /* bit 2 */ -#define MBEDTLS_X509_KU_DATA_ENCIPHERMENT (0x10) /* bit 3 */ -#define MBEDTLS_X509_KU_KEY_AGREEMENT (0x08) /* bit 4 */ -#define MBEDTLS_X509_KU_KEY_CERT_SIGN (0x04) /* bit 5 */ -#define MBEDTLS_X509_KU_CRL_SIGN (0x02) /* bit 6 */ -#define MBEDTLS_X509_KU_ENCIPHER_ONLY (0x01) /* bit 7 */ -#define MBEDTLS_X509_KU_DECIPHER_ONLY (0x8000) /* bit 8 */ - -/* - * Netscape certificate types - * (http://www.mozilla.org/projects/security/pki/nss/tech-notes/tn3.html) - */ - -#define MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT (0x80) /* bit 0 */ -#define MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER (0x40) /* bit 1 */ -#define MBEDTLS_X509_NS_CERT_TYPE_EMAIL (0x20) /* bit 2 */ -#define MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING (0x10) /* bit 3 */ -#define MBEDTLS_X509_NS_CERT_TYPE_RESERVED (0x08) /* bit 4 */ -#define MBEDTLS_X509_NS_CERT_TYPE_SSL_CA (0x04) /* bit 5 */ -#define MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA (0x02) /* bit 6 */ -#define MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA (0x01) /* bit 7 */ - -/* - * X.509 extension types - * - * Comments refer to the status for using certificates. Status can be - * different for writing certificates or reading CRLs or CSRs. - * - * Those are defined in oid.h as oid.c needs them in a data structure. Since - * these were previously defined here, let's have aliases for compatibility. - */ -#define MBEDTLS_X509_EXT_AUTHORITY_KEY_IDENTIFIER MBEDTLS_OID_X509_EXT_AUTHORITY_KEY_IDENTIFIER -#define MBEDTLS_X509_EXT_SUBJECT_KEY_IDENTIFIER MBEDTLS_OID_X509_EXT_SUBJECT_KEY_IDENTIFIER -#define MBEDTLS_X509_EXT_KEY_USAGE MBEDTLS_OID_X509_EXT_KEY_USAGE -#define MBEDTLS_X509_EXT_CERTIFICATE_POLICIES MBEDTLS_OID_X509_EXT_CERTIFICATE_POLICIES -#define MBEDTLS_X509_EXT_POLICY_MAPPINGS MBEDTLS_OID_X509_EXT_POLICY_MAPPINGS -#define MBEDTLS_X509_EXT_SUBJECT_ALT_NAME MBEDTLS_OID_X509_EXT_SUBJECT_ALT_NAME /* Supported (DNS) */ -#define MBEDTLS_X509_EXT_ISSUER_ALT_NAME MBEDTLS_OID_X509_EXT_ISSUER_ALT_NAME -#define MBEDTLS_X509_EXT_SUBJECT_DIRECTORY_ATTRS MBEDTLS_OID_X509_EXT_SUBJECT_DIRECTORY_ATTRS -#define MBEDTLS_X509_EXT_BASIC_CONSTRAINTS MBEDTLS_OID_X509_EXT_BASIC_CONSTRAINTS /* Supported */ -#define MBEDTLS_X509_EXT_NAME_CONSTRAINTS MBEDTLS_OID_X509_EXT_NAME_CONSTRAINTS -#define MBEDTLS_X509_EXT_POLICY_CONSTRAINTS MBEDTLS_OID_X509_EXT_POLICY_CONSTRAINTS -#define MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE MBEDTLS_OID_X509_EXT_EXTENDED_KEY_USAGE -#define MBEDTLS_X509_EXT_CRL_DISTRIBUTION_POINTS MBEDTLS_OID_X509_EXT_CRL_DISTRIBUTION_POINTS -#define MBEDTLS_X509_EXT_INIHIBIT_ANYPOLICY MBEDTLS_OID_X509_EXT_INIHIBIT_ANYPOLICY -#define MBEDTLS_X509_EXT_FRESHEST_CRL MBEDTLS_OID_X509_EXT_FRESHEST_CRL -#define MBEDTLS_X509_EXT_NS_CERT_TYPE MBEDTLS_OID_X509_EXT_NS_CERT_TYPE - -/* - * Storage format identifiers - * Recognized formats: PEM and DER - */ -#define MBEDTLS_X509_FORMAT_DER 1 -#define MBEDTLS_X509_FORMAT_PEM 2 - -#define MBEDTLS_X509_MAX_DN_NAME_SIZE 256 /**< Maximum value size of a DN entry */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \addtogroup x509_module - * \{ */ - -/** - * \name Structures for parsing X.509 certificates, CRLs and CSRs - * \{ - */ - -/** - * Type-length-value structure that allows for ASN1 using DER. - */ -typedef mbedtls_asn1_buf mbedtls_x509_buf; - -/** - * Container for ASN1 bit strings. - */ -typedef mbedtls_asn1_bitstring mbedtls_x509_bitstring; - -/** - * Container for ASN1 named information objects. - * It allows for Relative Distinguished Names (e.g. cn=localhost,ou=code,etc.). - */ -typedef mbedtls_asn1_named_data mbedtls_x509_name; - -/** - * Container for a sequence of ASN.1 items - */ -typedef mbedtls_asn1_sequence mbedtls_x509_sequence; - -/** Container for date and time (precision in seconds). */ -typedef struct mbedtls_x509_time -{ - int year, mon, day; /**< Date. */ - int hour, min, sec; /**< Time. */ -} -mbedtls_x509_time; - -/** \} name Structures for parsing X.509 certificates, CRLs and CSRs */ -/** \} addtogroup x509_module */ - -/** - * \brief Store the certificate DN in printable form into buf; - * no more than size characters will be written. - * - * \param buf Buffer to write to - * \param size Maximum size of buffer - * \param dn The X509 name to represent - * - * \return The length of the string written (not including the - * terminated nul byte), or a negative error code. - */ -int mbedtls_x509_dn_gets( char *buf, size_t size, const mbedtls_x509_name *dn ); - -/** - * \brief Store the certificate serial in printable form into buf; - * no more than size characters will be written. - * - * \param buf Buffer to write to - * \param size Maximum size of buffer - * \param serial The X509 serial to represent - * - * \return The length of the string written (not including the - * terminated nul byte), or a negative error code. - */ -int mbedtls_x509_serial_gets( char *buf, size_t size, const mbedtls_x509_buf *serial ); - -/** - * \brief Check a given mbedtls_x509_time against the system time - * and tell if it's in the past. - * - * \note Intended usage is "if( is_past( valid_to ) ) ERROR". - * Hence the return value of 1 if on internal errors. - * - * \param to mbedtls_x509_time to check - * - * \return 1 if the given time is in the past or an error occurred, - * 0 otherwise. - */ -int mbedtls_x509_time_is_past( const mbedtls_x509_time *to ); - -/** - * \brief Check a given mbedtls_x509_time against the system time - * and tell if it's in the future. - * - * \note Intended usage is "if( is_future( valid_from ) ) ERROR". - * Hence the return value of 1 if on internal errors. - * - * \param from mbedtls_x509_time to check - * - * \return 1 if the given time is in the future or an error occurred, - * 0 otherwise. - */ -int mbedtls_x509_time_is_future( const mbedtls_x509_time *from ); - -#if defined(MBEDTLS_SELF_TEST) - -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if the test failed - */ -int mbedtls_x509_self_test( int verbose ); - -#endif /* MBEDTLS_SELF_TEST */ - -/* - * Internal module functions. You probably do not want to use these unless you - * know you do. - */ -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_type_t *pk_alg, - void **sig_opts ); -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 ); -int mbedtls_x509_sig_alg_gets( char *buf, size_t size, const mbedtls_x509_buf *sig_oid, - mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg, - const void *sig_opts ); -int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char *name ); -int mbedtls_x509_string_to_names( mbedtls_asn1_named_data **head, 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 ); - -#define MBEDTLS_X509_SAFE_SNPRINTF \ - do { \ - if( ret < 0 || (size_t) ret >= n ) \ - return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL ); \ - \ - n -= (size_t) ret; \ - p += (size_t) ret; \ - } while( 0 ) - -#ifdef __cplusplus -} -#endif - -#endif /* x509.h */ diff --git a/include/mbedtls/x509_crl.h b/include/mbedtls/x509_crl.h deleted file mode 100644 index fa838d68c..000000000 --- a/include/mbedtls/x509_crl.h +++ /dev/null @@ -1,174 +0,0 @@ -/** - * \file x509_crl.h - * - * \brief X.509 certificate revocation list parsing - */ -/* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -#ifndef MBEDTLS_X509_CRL_H -#define MBEDTLS_X509_CRL_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "x509.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \addtogroup x509_module - * \{ */ - -/** - * \name Structures and functions for parsing CRLs - * \{ - */ - -/** - * Certificate revocation list entry. - * Contains the CA-specific serial numbers and revocation dates. - */ -typedef struct mbedtls_x509_crl_entry -{ - mbedtls_x509_buf raw; - - mbedtls_x509_buf serial; - - mbedtls_x509_time revocation_date; - - mbedtls_x509_buf entry_ext; - - struct mbedtls_x509_crl_entry *next; -} -mbedtls_x509_crl_entry; - -/** - * Certificate revocation list structure. - * Every CRL may have multiple entries. - */ -typedef struct mbedtls_x509_crl -{ - mbedtls_x509_buf raw; /**< The raw certificate data (DER). */ - mbedtls_x509_buf tbs; /**< The raw certificate body (DER). The part that is To Be Signed. */ - - int version; /**< CRL version (1=v1, 2=v2) */ - mbedtls_x509_buf sig_oid; /**< CRL signature type identifier */ - - mbedtls_x509_buf issuer_raw; /**< The raw issuer data (DER). */ - - mbedtls_x509_name issuer; /**< The parsed issuer data (named information object). */ - - mbedtls_x509_time this_update; - mbedtls_x509_time next_update; - - mbedtls_x509_crl_entry entry; /**< The CRL entries containing the certificate revocation times for this CA. */ - - mbedtls_x509_buf crl_ext; - - mbedtls_x509_buf sig_oid2; - mbedtls_x509_buf sig; - mbedtls_md_type_t sig_md; /**< Internal representation of the MD algorithm of the signature algorithm, e.g. MBEDTLS_MD_SHA256 */ - mbedtls_pk_type_t sig_pk; /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */ - void *sig_opts; /**< Signature options to be passed to mbedtls_pk_verify_ext(), e.g. for RSASSA-PSS */ - - struct mbedtls_x509_crl *next; -} -mbedtls_x509_crl; - -/** - * \brief Parse a DER-encoded CRL and append it to the chained list - * - * \param chain points to the start of the chain - * \param buf buffer holding the CRL data in DER format - * \param buflen size of the buffer - * (including the terminating null byte for PEM data) - * - * \return 0 if successful, or a specific X509 or PEM error code - */ -int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain, - const unsigned char *buf, size_t buflen ); -/** - * \brief Parse one or more CRLs and append them to the chained list - * - * \note Multiple CRLs are accepted only if using PEM format - * - * \param chain points to the start of the chain - * \param buf buffer holding the CRL data in PEM or DER format - * \param buflen size of the buffer - * (including the terminating null byte for PEM data) - * - * \return 0 if successful, or a specific X509 or PEM error code - */ -int mbedtls_x509_crl_parse( mbedtls_x509_crl *chain, const unsigned char *buf, size_t buflen ); - -#if defined(MBEDTLS_FS_IO) -/** - * \brief Load one or more CRLs and append them to the chained list - * - * \note Multiple CRLs are accepted only if using PEM format - * - * \param chain points to the start of the chain - * \param path filename to read the CRLs from (in PEM or DER encoding) - * - * \return 0 if successful, or a specific X509 or PEM error code - */ -int mbedtls_x509_crl_parse_file( mbedtls_x509_crl *chain, const char *path ); -#endif /* MBEDTLS_FS_IO */ - -/** - * \brief Returns an informational string about the CRL. - * - * \param buf Buffer to write to - * \param size Maximum size of buffer - * \param prefix A line prefix - * \param crl The X509 CRL to represent - * - * \return The length of the string written (not including the - * terminated nul byte), or a negative error code. - */ -int mbedtls_x509_crl_info( char *buf, size_t size, const char *prefix, - const mbedtls_x509_crl *crl ); - -/** - * \brief Initialize a CRL (chain) - * - * \param crl CRL chain to initialize - */ -void mbedtls_x509_crl_init( mbedtls_x509_crl *crl ); - -/** - * \brief Unallocate all CRL data - * - * \param crl CRL chain to free - */ -void mbedtls_x509_crl_free( mbedtls_x509_crl *crl ); - -/* \} name */ -/* \} addtogroup x509_module */ - -#ifdef __cplusplus -} -#endif - -#endif /* mbedtls_x509_crl.h */ diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h deleted file mode 100644 index eea263201..000000000 --- a/include/mbedtls/x509_crt.h +++ /dev/null @@ -1,921 +0,0 @@ -/** - * \file x509_crt.h - * - * \brief X.509 certificate parsing and writing - */ -/* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -#ifndef MBEDTLS_X509_CRT_H -#define MBEDTLS_X509_CRT_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "x509.h" -#include "x509_crl.h" - -/** - * \addtogroup x509_module - * \{ - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \name Structures and functions for parsing and writing X.509 certificates - * \{ - */ - -/** - * Container for an X.509 certificate. The certificate may be chained. - */ -typedef struct mbedtls_x509_crt -{ - int own_buffer; /**< Indicates if \c raw is owned - * by the structure or not. */ - mbedtls_x509_buf raw; /**< The raw certificate data (DER). */ - mbedtls_x509_buf tbs; /**< The raw certificate body (DER). The part that is To Be Signed. */ - - int version; /**< The X.509 version. (1=v1, 2=v2, 3=v3) */ - mbedtls_x509_buf serial; /**< Unique id for certificate issued by a specific CA. */ - mbedtls_x509_buf sig_oid; /**< Signature algorithm, e.g. sha1RSA */ - - mbedtls_x509_buf issuer_raw; /**< The raw issuer data (DER). Used for quick comparison. */ - mbedtls_x509_buf subject_raw; /**< The raw subject data (DER). Used for quick comparison. */ - - mbedtls_x509_name issuer; /**< The parsed issuer data (named information object). */ - mbedtls_x509_name subject; /**< The parsed subject data (named information object). */ - - mbedtls_x509_time valid_from; /**< Start time of certificate validity. */ - mbedtls_x509_time valid_to; /**< End time of certificate validity. */ - - mbedtls_x509_buf pk_raw; - mbedtls_pk_context pk; /**< Container for the public key context. */ - - mbedtls_x509_buf issuer_id; /**< Optional X.509 v2/v3 issuer unique identifier. */ - mbedtls_x509_buf subject_id; /**< Optional X.509 v2/v3 subject unique identifier. */ - mbedtls_x509_buf v3_ext; /**< Optional X.509 v3 extensions. */ - mbedtls_x509_sequence subject_alt_names; /**< Optional list of Subject Alternative Names (Only dNSName supported). */ - - int ext_types; /**< Bit string containing detected and parsed extensions */ - int ca_istrue; /**< Optional Basic Constraint extension value: 1 if this certificate belongs to a CA, 0 otherwise. */ - int max_pathlen; /**< Optional Basic Constraint extension value: The maximum path length to the root certificate. Path length is 1 higher than RFC 5280 'meaning', so 1+ */ - - unsigned int key_usage; /**< Optional key usage extension value: See the values in x509.h */ - - mbedtls_x509_sequence ext_key_usage; /**< Optional list of extended key usage OIDs. */ - - unsigned char ns_cert_type; /**< Optional Netscape certificate type extension value: See the values in x509.h */ - - mbedtls_x509_buf sig; /**< Signature: hash of the tbs part signed with the private key. */ - mbedtls_md_type_t sig_md; /**< Internal representation of the MD algorithm of the signature algorithm, e.g. MBEDTLS_MD_SHA256 */ - mbedtls_pk_type_t sig_pk; /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */ - void *sig_opts; /**< Signature options to be passed to mbedtls_pk_verify_ext(), e.g. for RSASSA-PSS */ - - struct mbedtls_x509_crt *next; /**< Next certificate in the CA-chain. */ -} -mbedtls_x509_crt; - -/** - * Build flag from an algorithm/curve identifier (pk, md, ecp) - * Since 0 is always XXX_NONE, ignore it. - */ -#define MBEDTLS_X509_ID_FLAG( id ) ( 1 << ( id - 1 ) ) - -/** - * Security profile for certificate verification. - * - * All lists are bitfields, built by ORing flags from MBEDTLS_X509_ID_FLAG(). - */ -typedef struct mbedtls_x509_crt_profile -{ - uint32_t allowed_mds; /**< MDs for signatures */ - uint32_t allowed_pks; /**< PK algs for signatures */ - uint32_t allowed_curves; /**< Elliptic curves for ECDSA */ - uint32_t rsa_min_bitlen; /**< Minimum size for RSA keys */ -} -mbedtls_x509_crt_profile; - -#define MBEDTLS_X509_CRT_VERSION_1 0 -#define MBEDTLS_X509_CRT_VERSION_2 1 -#define MBEDTLS_X509_CRT_VERSION_3 2 - -#define MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN 32 -#define MBEDTLS_X509_RFC5280_UTC_TIME_LEN 15 - -#if !defined( MBEDTLS_X509_MAX_FILE_PATH_LEN ) -#define MBEDTLS_X509_MAX_FILE_PATH_LEN 512 -#endif - -/** - * Container for writing a certificate (CRT) - */ -typedef struct mbedtls_x509write_cert -{ - int version; - mbedtls_mpi serial; - mbedtls_pk_context *subject_key; - mbedtls_pk_context *issuer_key; - mbedtls_asn1_named_data *subject; - mbedtls_asn1_named_data *issuer; - mbedtls_md_type_t md_alg; - char not_before[MBEDTLS_X509_RFC5280_UTC_TIME_LEN + 1]; - char not_after[MBEDTLS_X509_RFC5280_UTC_TIME_LEN + 1]; - mbedtls_asn1_named_data *extensions; -} -mbedtls_x509write_cert; - -/** - * Item in a verification chain: cert and flags for it - */ -typedef struct { - mbedtls_x509_crt *crt; - uint32_t flags; -} mbedtls_x509_crt_verify_chain_item; - -/** - * Max size of verification chain: end-entity + intermediates + trusted root - */ -#define MBEDTLS_X509_MAX_VERIFY_CHAIN_SIZE ( MBEDTLS_X509_MAX_INTERMEDIATE_CA + 2 ) - -/** - * Verification chain as built by \c mbedtls_crt_verify_chain() - */ -typedef struct -{ - mbedtls_x509_crt_verify_chain_item items[MBEDTLS_X509_MAX_VERIFY_CHAIN_SIZE]; - unsigned len; - -#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) - /* This stores the list of potential trusted signers obtained from - * the CA callback used for the CRT verification, if configured. - * We must track it somewhere because the callback passes its - * ownership to the caller. */ - mbedtls_x509_crt *trust_ca_cb_result; -#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */ -} mbedtls_x509_crt_verify_chain; - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - -/** - * \brief Context for resuming X.509 verify operations - */ -typedef struct -{ - /* for check_signature() */ - mbedtls_pk_restart_ctx pk; - - /* for find_parent_in() */ - mbedtls_x509_crt *parent; /* non-null iff parent_in in progress */ - mbedtls_x509_crt *fallback_parent; - int fallback_signature_is_good; - - /* for find_parent() */ - int parent_is_trusted; /* -1 if find_parent is not in progress */ - - /* for verify_chain() */ - enum { - x509_crt_rs_none, - x509_crt_rs_find_parent, - } in_progress; /* none if no operation is in progress */ - int self_cnt; - mbedtls_x509_crt_verify_chain ver_chain; - -} mbedtls_x509_crt_restart_ctx; - -#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - -/* Now we can declare functions that take a pointer to that */ -typedef void mbedtls_x509_crt_restart_ctx; - -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -/** - * Default security profile. Should provide a good balance between security - * and compatibility with current deployments. - */ -extern const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default; - -/** - * Expected next default profile. Recommended for new deployments. - * Currently targets a 128-bit security level, except for RSA-2048. - */ -extern const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_next; - -/** - * NSA Suite B profile. - */ -extern const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb; - -/** - * \brief Parse a single DER formatted certificate and add it - * to the end of the provided chained list. - * - * \param chain The pointer to the start of the CRT chain to attach to. - * When parsing the first CRT in a chain, this should point - * to an instance of ::mbedtls_x509_crt initialized through - * mbedtls_x509_crt_init(). - * \param buf The buffer holding the DER encoded certificate. - * \param buflen The size in Bytes of \p buf. - * - * \note This function makes an internal copy of the CRT buffer - * \p buf. In particular, \p buf may be destroyed or reused - * after this call returns. To avoid duplicating the CRT - * buffer (at the cost of stricter lifetime constraints), - * use mbedtls_x509_crt_parse_der_nocopy() instead. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, - const unsigned char *buf, - size_t buflen ); - -/** - * \brief Parse a single DER formatted certificate and add it - * to the end of the provided chained list. This is a - * variant of mbedtls_x509_crt_parse_der() which takes - * temporary ownership of the CRT buffer until the CRT - * is destroyed. - * - * \param chain The pointer to the start of the CRT chain to attach to. - * When parsing the first CRT in a chain, this should point - * to an instance of ::mbedtls_x509_crt initialized through - * mbedtls_x509_crt_init(). - * \param buf The address of the readable buffer holding the DER encoded - * certificate to use. On success, this buffer must be - * retained and not be changed for the liftetime of the - * CRT chain \p chain, that is, until \p chain is destroyed - * through a call to mbedtls_x509_crt_free(). - * \param buflen The size in Bytes of \p buf. - * - * \note This call is functionally equivalent to - * mbedtls_x509_crt_parse_der(), but it avoids creating a - * copy of the input buffer at the cost of stronger lifetime - * constraints. This is useful in constrained environments - * where duplication of the CRT cannot be tolerated. - * - * \return \c 0 if successful. - * \return A negative error code on failure. - */ -int mbedtls_x509_crt_parse_der_nocopy( mbedtls_x509_crt *chain, - const unsigned char *buf, - size_t buflen ); - -/** - * \brief Parse one DER-encoded or one or more concatenated PEM-encoded - * certificates and add them to the chained list. - * - * For CRTs in PEM encoding, the function parses permissively: - * if at least one certificate can be parsed, the function - * returns the number of certificates for which parsing failed - * (hence \c 0 if all certificates were parsed successfully). - * If no certificate could be parsed, the function returns - * the first (negative) error encountered during parsing. - * - * PEM encoded certificates may be interleaved by other data - * such as human readable descriptions of their content, as - * long as the certificates are enclosed in the PEM specific - * '-----{BEGIN/END} CERTIFICATE-----' delimiters. - * - * \param chain The chain to which to add the parsed certificates. - * \param buf The buffer holding the certificate data in PEM or DER format. - * For certificates in PEM encoding, this may be a concatenation - * of multiple certificates; for DER encoding, the buffer must - * comprise exactly one certificate. - * \param buflen The size of \p buf, including the terminating \c NULL byte - * in case of PEM encoded data. - * - * \return \c 0 if all certificates were parsed successfully. - * \return The (positive) number of certificates that couldn't - * be parsed if parsing was partly successful (see above). - * \return A negative X509 or PEM error code otherwise. - * - */ -int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, size_t buflen ); - -#if defined(MBEDTLS_FS_IO) -/** - * \brief Load one or more certificates and add them - * to the chained list. Parses permissively. If some - * certificates can be parsed, the result is the number - * of failed certificates it encountered. If none complete - * correctly, the first error is returned. - * - * \param chain points to the start of the chain - * \param path filename to read the certificates from - * - * \return 0 if all certificates parsed successfully, a positive number - * if partly successful or a specific X509 or PEM error code - */ -int mbedtls_x509_crt_parse_file( mbedtls_x509_crt *chain, const char *path ); - -/** - * \brief Load one or more certificate files from a path and add them - * to the chained list. Parses permissively. If some - * certificates can be parsed, the result is the number - * of failed certificates it encountered. If none complete - * correctly, the first error is returned. - * - * \param chain points to the start of the chain - * \param path directory / folder to read the certificate files from - * - * \return 0 if all certificates parsed successfully, a positive number - * if partly successful or a specific X509 or PEM error code - */ -int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ); -#endif /* MBEDTLS_FS_IO */ - -/** - * \brief Returns an informational string about the - * certificate. - * - * \param buf Buffer to write to - * \param size Maximum size of buffer - * \param prefix A line prefix - * \param crt The X509 certificate to represent - * - * \return The length of the string written (not including the - * terminated nul byte), or a negative error code. - */ -int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix, - const mbedtls_x509_crt *crt ); - -/** - * \brief Returns an informational string about the - * verification status of a certificate. - * - * \param buf Buffer to write to - * \param size Maximum size of buffer - * \param prefix A line prefix - * \param flags Verification flags created by mbedtls_x509_crt_verify() - * - * \return The length of the string written (not including the - * terminated nul byte), or a negative error code. - */ -int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix, - uint32_t flags ); - -/** - * \brief Verify a chain of certificates. - * - * The verify callback is a user-supplied callback that - * can clear / modify / add flags for a certificate. If set, - * the verification callback is called for each - * certificate in the chain (from the trust-ca down to the - * presented crt). The parameters for the callback are: - * (void *parameter, mbedtls_x509_crt *crt, int certificate_depth, - * int *flags). With the flags representing current flags for - * that specific certificate and the certificate depth from - * the bottom (Peer cert depth = 0). - * - * All flags left after returning from the callback - * are also returned to the application. The function should - * return 0 for anything (including invalid certificates) - * other than fatal error, as a non-zero return code - * immediately aborts the verification process. For fatal - * errors, a specific error code should be used (different - * from MBEDTLS_ERR_X509_CERT_VERIFY_FAILED which should not - * be returned at this point), or MBEDTLS_ERR_X509_FATAL_ERROR - * can be used if no better code is available. - * - * \note In case verification failed, the results can be displayed - * using \c mbedtls_x509_crt_verify_info() - * - * \note Same as \c mbedtls_x509_crt_verify_with_profile() with the - * default security profile. - * - * \note It is your responsibility to provide up-to-date CRLs for - * all trusted CAs. If no CRL is provided for the CA that was - * used to sign the certificate, CRL verification is skipped - * silently, that is *without* setting any flag. - * - * \note The \c trust_ca list can contain two types of certificates: - * (1) those of trusted root CAs, so that certificates - * chaining up to those CAs will be trusted, and (2) - * self-signed end-entity certificates to be trusted (for - * specific peers you know) - in that case, the self-signed - * certificate doesn't need to have the CA bit set. - * - * \param crt The certificate chain to be verified. - * \param trust_ca The list of trusted CAs. - * \param ca_crl The list of CRLs for trusted CAs. - * \param cn The expected Common Name. This may be \c NULL if the - * CN need not be verified. - * \param flags The address at which to store the result of the verification. - * If the verification couldn't be completed, the flag value is - * set to (uint32_t) -1. - * \param f_vrfy The verification callback to use. See the documentation - * of mbedtls_x509_crt_verify() for more information. - * \param p_vrfy The context to be passed to \p f_vrfy. - * - * \return \c 0 if the chain is valid with respect to the - * passed CN, CAs, CRLs and security profile. - * \return #MBEDTLS_ERR_X509_CERT_VERIFY_FAILED in case the - * certificate chain verification failed. In this case, - * \c *flags will have one or more - * \c MBEDTLS_X509_BADCERT_XXX or \c MBEDTLS_X509_BADCRL_XXX - * flags set. - * \return Another negative error code in case of a fatal error - * encountered during the verification process. - */ -int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt, - mbedtls_x509_crt *trust_ca, - mbedtls_x509_crl *ca_crl, - const char *cn, uint32_t *flags, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy ); - -/** - * \brief Verify a chain of certificates with respect to - * a configurable security profile. - * - * \note Same as \c mbedtls_x509_crt_verify(), but with explicit - * security profile. - * - * \note The restrictions on keys (RSA minimum size, allowed curves - * for ECDSA) apply to all certificates: trusted root, - * intermediate CAs if any, and end entity certificate. - * - * \param crt The certificate chain to be verified. - * \param trust_ca The list of trusted CAs. - * \param ca_crl The list of CRLs for trusted CAs. - * \param profile The security profile to use for the verification. - * \param cn The expected Common Name. This may be \c NULL if the - * CN need not be verified. - * \param flags The address at which to store the result of the verification. - * If the verification couldn't be completed, the flag value is - * set to (uint32_t) -1. - * \param f_vrfy The verification callback to use. See the documentation - * of mbedtls_x509_crt_verify() for more information. - * \param p_vrfy The context to be passed to \p f_vrfy. - * - * \return \c 0 if the chain is valid with respect to the - * passed CN, CAs, CRLs and security profile. - * \return #MBEDTLS_ERR_X509_CERT_VERIFY_FAILED in case the - * certificate chain verification failed. In this case, - * \c *flags will have one or more - * \c MBEDTLS_X509_BADCERT_XXX or \c MBEDTLS_X509_BADCRL_XXX - * flags set. - * \return Another negative error code in case of a fatal error - * encountered during the verification process. - */ -int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt, - mbedtls_x509_crt *trust_ca, - mbedtls_x509_crl *ca_crl, - const mbedtls_x509_crt_profile *profile, - const char *cn, uint32_t *flags, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy ); - -/** - * \brief Restartable version of \c mbedtls_crt_verify_with_profile() - * - * \note Performs the same job as \c mbedtls_crt_verify_with_profile() - * but can return early and restart according to the limit - * set with \c mbedtls_ecp_set_max_ops() to reduce blocking. - * - * \param crt The certificate chain to be verified. - * \param trust_ca The list of trusted CAs. - * \param ca_crl The list of CRLs for trusted CAs. - * \param profile The security profile to use for the verification. - * \param cn The expected Common Name. This may be \c NULL if the - * CN need not be verified. - * \param flags The address at which to store the result of the verification. - * If the verification couldn't be completed, the flag value is - * set to (uint32_t) -1. - * \param f_vrfy The verification callback to use. See the documentation - * of mbedtls_x509_crt_verify() for more information. - * \param p_vrfy The context to be passed to \p f_vrfy. - * \param rs_ctx The restart context to use. This may be set to \c NULL - * to disable restartable ECC. - * - * \return See \c mbedtls_crt_verify_with_profile(), or - * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of - * operations was reached: see \c mbedtls_ecp_set_max_ops(). - */ -int mbedtls_x509_crt_verify_restartable( mbedtls_x509_crt *crt, - mbedtls_x509_crt *trust_ca, - mbedtls_x509_crl *ca_crl, - const mbedtls_x509_crt_profile *profile, - const char *cn, uint32_t *flags, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy, - mbedtls_x509_crt_restart_ctx *rs_ctx ); - -/** - * \brief The type of trusted certificate callbacks. - * - * Callbacks of this type are passed to and used by the CRT - * verification routine mbedtls_x509_crt_verify_with_ca_cb() - * when looking for trusted signers of a given certificate. - * - * On success, the callback returns a list of trusted - * certificates to be considered as potential signers - * for the input certificate. - * - * \param p_ctx An opaque context passed to the callback. - * \param child The certificate for which to search a potential signer. - * This will point to a readable certificate. - * \param candidate_cas The address at which to store the address of the first - * entry in the generated linked list of candidate signers. - * This will not be \c NULL. - * - * \note The callback must only return a non-zero value on a - * fatal error. If, in contrast, the search for a potential - * signer completes without a single candidate, the - * callback must return \c 0 and set \c *candidate_cas - * to \c NULL. - * - * \return \c 0 on success. In this case, \c *candidate_cas points - * to a heap-allocated linked list of instances of - * ::mbedtls_x509_crt, and ownership of this list is passed - * to the caller. - * \return A negative error code on failure. - */ -typedef int (*mbedtls_x509_crt_ca_cb_t)( void *p_ctx, - mbedtls_x509_crt const *child, - mbedtls_x509_crt **candidate_cas ); - -#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) -/** - * \brief Version of \c mbedtls_x509_crt_verify_with_profile() which - * uses a callback to acquire the list of trusted CA - * certificates. - * - * \param crt The certificate chain to be verified. - * \param f_ca_cb The callback to be used to query for potential signers - * of a given child certificate. See the documentation of - * ::mbedtls_x509_crt_ca_cb_t for more information. - * \param p_ca_cb The opaque context to be passed to \p f_ca_cb. - * \param profile The security profile for the verification. - * \param cn The expected Common Name. This may be \c NULL if the - * CN need not be verified. - * \param flags The address at which to store the result of the verification. - * If the verification couldn't be completed, the flag value is - * set to (uint32_t) -1. - * \param f_vrfy The verification callback to use. See the documentation - * of mbedtls_x509_crt_verify() for more information. - * \param p_vrfy The context to be passed to \p f_vrfy. - * - * \return See \c mbedtls_crt_verify_with_profile(). - */ -int mbedtls_x509_crt_verify_with_ca_cb( mbedtls_x509_crt *crt, - mbedtls_x509_crt_ca_cb_t f_ca_cb, - void *p_ca_cb, - const mbedtls_x509_crt_profile *profile, - const char *cn, uint32_t *flags, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy ); - -#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */ - -#if defined(MBEDTLS_X509_CHECK_KEY_USAGE) -/** - * \brief Check usage of certificate against keyUsage extension. - * - * \param crt Leaf certificate used. - * \param usage Intended usage(s) (eg MBEDTLS_X509_KU_KEY_ENCIPHERMENT - * before using the certificate to perform an RSA key - * exchange). - * - * \note Except for decipherOnly and encipherOnly, a bit set in the - * usage argument means this bit MUST be set in the - * certificate. For decipherOnly and encipherOnly, it means - * that bit MAY be set. - * - * \return 0 is these uses of the certificate are allowed, - * MBEDTLS_ERR_X509_BAD_INPUT_DATA if the keyUsage extension - * is present but does not match the usage argument. - * - * \note You should only call this function on leaf certificates, on - * (intermediate) CAs the keyUsage extension is automatically - * checked by \c mbedtls_x509_crt_verify(). - */ -int mbedtls_x509_crt_check_key_usage( const mbedtls_x509_crt *crt, - unsigned int usage ); -#endif /* MBEDTLS_X509_CHECK_KEY_USAGE) */ - -#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE) -/** - * \brief Check usage of certificate against extendedKeyUsage. - * - * \param crt Leaf certificate used. - * \param usage_oid Intended usage (eg MBEDTLS_OID_SERVER_AUTH or - * MBEDTLS_OID_CLIENT_AUTH). - * \param usage_len Length of usage_oid (eg given by MBEDTLS_OID_SIZE()). - * - * \return 0 if this use of the certificate is allowed, - * MBEDTLS_ERR_X509_BAD_INPUT_DATA if not. - * - * \note Usually only makes sense on leaf certificates. - */ -int mbedtls_x509_crt_check_extended_key_usage( const mbedtls_x509_crt *crt, - const char *usage_oid, - size_t usage_len ); -#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */ - -#if defined(MBEDTLS_X509_CRL_PARSE_C) -/** - * \brief Verify the certificate revocation status - * - * \param crt a certificate to be verified - * \param crl the CRL to verify against - * - * \return 1 if the certificate is revoked, 0 otherwise - * - */ -int mbedtls_x509_crt_is_revoked( const mbedtls_x509_crt *crt, const mbedtls_x509_crl *crl ); -#endif /* MBEDTLS_X509_CRL_PARSE_C */ - -/** - * \brief Initialize a certificate (chain) - * - * \param crt Certificate chain to initialize - */ -void mbedtls_x509_crt_init( mbedtls_x509_crt *crt ); - -/** - * \brief Unallocate all certificate data - * - * \param crt Certificate chain to free - */ -void mbedtls_x509_crt_free( mbedtls_x509_crt *crt ); - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) -/** - * \brief Initialize a restart context - */ -void mbedtls_x509_crt_restart_init( mbedtls_x509_crt_restart_ctx *ctx ); - -/** - * \brief Free the components of a restart context - */ -void mbedtls_x509_crt_restart_free( mbedtls_x509_crt_restart_ctx *ctx ); -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -/* \} name */ -/* \} addtogroup x509_module */ - -#if defined(MBEDTLS_X509_CRT_WRITE_C) -/** - * \brief Initialize a CRT writing context - * - * \param ctx CRT context to initialize - */ -void mbedtls_x509write_crt_init( mbedtls_x509write_cert *ctx ); - -/** - * \brief Set the verion for a Certificate - * Default: MBEDTLS_X509_CRT_VERSION_3 - * - * \param ctx CRT context to use - * \param version version to set (MBEDTLS_X509_CRT_VERSION_1, MBEDTLS_X509_CRT_VERSION_2 or - * MBEDTLS_X509_CRT_VERSION_3) - */ -void mbedtls_x509write_crt_set_version( mbedtls_x509write_cert *ctx, int version ); - -/** - * \brief Set the serial number for a Certificate. - * - * \param ctx CRT context to use - * \param serial serial number to set - * - * \return 0 if successful - */ -int mbedtls_x509write_crt_set_serial( mbedtls_x509write_cert *ctx, const mbedtls_mpi *serial ); - -/** - * \brief Set the validity period for a Certificate - * Timestamps should be in string format for UTC timezone - * i.e. "YYYYMMDDhhmmss" - * e.g. "20131231235959" for December 31st 2013 - * at 23:59:59 - * - * \param ctx CRT context to use - * \param not_before not_before timestamp - * \param not_after not_after timestamp - * - * \return 0 if timestamp was parsed successfully, or - * a specific error code - */ -int mbedtls_x509write_crt_set_validity( mbedtls_x509write_cert *ctx, const char *not_before, - const char *not_after ); - -/** - * \brief Set the issuer name for a Certificate - * Issuer names should contain a comma-separated list - * of OID types and values: - * e.g. "C=UK,O=ARM,CN=mbed TLS CA" - * - * \param ctx CRT context to use - * \param issuer_name issuer name to set - * - * \return 0 if issuer name was parsed successfully, or - * a specific error code - */ -int mbedtls_x509write_crt_set_issuer_name( mbedtls_x509write_cert *ctx, - const char *issuer_name ); - -/** - * \brief Set the subject name for a Certificate - * Subject names should contain a comma-separated list - * of OID types and values: - * e.g. "C=UK,O=ARM,CN=mbed TLS Server 1" - * - * \param ctx CRT context to use - * \param subject_name subject name to set - * - * \return 0 if subject name was parsed successfully, or - * a specific error code - */ -int mbedtls_x509write_crt_set_subject_name( mbedtls_x509write_cert *ctx, - const char *subject_name ); - -/** - * \brief Set the subject public key for the certificate - * - * \param ctx CRT context to use - * \param key public key to include - */ -void mbedtls_x509write_crt_set_subject_key( mbedtls_x509write_cert *ctx, mbedtls_pk_context *key ); - -/** - * \brief Set the issuer key used for signing the certificate - * - * \param ctx CRT context to use - * \param key private key to sign with - */ -void mbedtls_x509write_crt_set_issuer_key( mbedtls_x509write_cert *ctx, mbedtls_pk_context *key ); - -/** - * \brief Set the MD algorithm to use for the signature - * (e.g. MBEDTLS_MD_SHA1) - * - * \param ctx CRT context to use - * \param md_alg MD algorithm to use - */ -void mbedtls_x509write_crt_set_md_alg( mbedtls_x509write_cert *ctx, mbedtls_md_type_t md_alg ); - -/** - * \brief Generic function to add to or replace an extension in the - * CRT - * - * \param ctx CRT context to use - * \param oid OID of the extension - * \param oid_len length of the OID - * \param critical if the extension is critical (per the RFC's definition) - * \param val value of the extension OCTET STRING - * \param val_len length of the value data - * - * \return 0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED - */ -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 ); - -/** - * \brief Set the basicConstraints extension for a CRT - * - * \param ctx CRT context to use - * \param is_ca is this a CA certificate - * \param max_pathlen maximum length of certificate chains below this - * certificate (only for CA certificates, -1 is - * inlimited) - * - * \return 0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED - */ -int mbedtls_x509write_crt_set_basic_constraints( mbedtls_x509write_cert *ctx, - int is_ca, int max_pathlen ); - -#if defined(MBEDTLS_SHA1_C) -/** - * \brief Set the subjectKeyIdentifier extension for a CRT - * Requires that mbedtls_x509write_crt_set_subject_key() has been - * called before - * - * \param ctx CRT context to use - * - * \return 0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED - */ -int mbedtls_x509write_crt_set_subject_key_identifier( mbedtls_x509write_cert *ctx ); - -/** - * \brief Set the authorityKeyIdentifier extension for a CRT - * Requires that mbedtls_x509write_crt_set_issuer_key() has been - * called before - * - * \param ctx CRT context to use - * - * \return 0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED - */ -int mbedtls_x509write_crt_set_authority_key_identifier( mbedtls_x509write_cert *ctx ); -#endif /* MBEDTLS_SHA1_C */ - -/** - * \brief Set the Key Usage Extension flags - * (e.g. MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_KEY_CERT_SIGN) - * - * \param ctx CRT context to use - * \param key_usage key usage flags to set - * - * \return 0 if successful, or MBEDTLS_ERR_X509_ALLOC_FAILED - */ -int mbedtls_x509write_crt_set_key_usage( mbedtls_x509write_cert *ctx, - unsigned int key_usage ); - -/** - * \brief Set the Netscape Cert Type flags - * (e.g. MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT | MBEDTLS_X509_NS_CERT_TYPE_EMAIL) - * - * \param ctx CRT context to use - * \param ns_cert_type Netscape Cert Type flags to set - * - * \return 0 if successful, or MBEDTLS_ERR_X509_ALLOC_FAILED - */ -int mbedtls_x509write_crt_set_ns_cert_type( mbedtls_x509write_cert *ctx, - unsigned char ns_cert_type ); - -/** - * \brief Free the contents of a CRT write context - * - * \param ctx CRT context to free - */ -void mbedtls_x509write_crt_free( mbedtls_x509write_cert *ctx ); - -/** - * \brief Write a built up certificate to a X509 DER structure - * Note: data is written at the end of the buffer! Use the - * return value to determine where you should start - * using the buffer - * - * \param ctx certificate to write away - * \param buf buffer to write to - * \param size size of the buffer - * \param f_rng RNG function (for signature, see note) - * \param p_rng RNG parameter - * - * \return length of data written if successful, or a specific - * error code - * - * \note f_rng may be NULL if RSA is used for signature and the - * signature is made offline (otherwise f_rng is desirable - * for countermeasures against timing attacks). - * ECDSA signatures always require a non-NULL f_rng. - */ -int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf, size_t size, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); - -#if defined(MBEDTLS_PEM_WRITE_C) -/** - * \brief Write a built up certificate to a X509 PEM string - * - * \param ctx certificate to write away - * \param buf buffer to write to - * \param size size of the buffer - * \param f_rng RNG function (for signature, see note) - * \param p_rng RNG parameter - * - * \return 0 if successful, or a specific error code - * - * \note f_rng may be NULL if RSA is used for signature and the - * signature is made offline (otherwise f_rng is desirable - * for countermeasures against timing attacks). - * ECDSA signatures always require a non-NULL f_rng. - */ -int mbedtls_x509write_crt_pem( mbedtls_x509write_cert *ctx, unsigned char *buf, size_t size, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); -#endif /* MBEDTLS_PEM_WRITE_C */ -#endif /* MBEDTLS_X509_CRT_WRITE_C */ - -#ifdef __cplusplus -} -#endif - -#endif /* mbedtls_x509_crt.h */ diff --git a/include/mbedtls/x509_csr.h b/include/mbedtls/x509_csr.h deleted file mode 100644 index a3c28048e..000000000 --- a/include/mbedtls/x509_csr.h +++ /dev/null @@ -1,307 +0,0 @@ -/** - * \file x509_csr.h - * - * \brief X.509 certificate signing request parsing and writing - */ -/* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -#ifndef MBEDTLS_X509_CSR_H -#define MBEDTLS_X509_CSR_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "x509.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \addtogroup x509_module - * \{ */ - -/** - * \name Structures and functions for X.509 Certificate Signing Requests (CSR) - * \{ - */ - -/** - * Certificate Signing Request (CSR) structure. - */ -typedef struct mbedtls_x509_csr -{ - mbedtls_x509_buf raw; /**< The raw CSR data (DER). */ - mbedtls_x509_buf cri; /**< The raw CertificateRequestInfo body (DER). */ - - int version; /**< CSR version (1=v1). */ - - mbedtls_x509_buf subject_raw; /**< The raw subject data (DER). */ - mbedtls_x509_name subject; /**< The parsed subject data (named information object). */ - - mbedtls_pk_context pk; /**< Container for the public key context. */ - - mbedtls_x509_buf sig_oid; - mbedtls_x509_buf sig; - mbedtls_md_type_t sig_md; /**< Internal representation of the MD algorithm of the signature algorithm, e.g. MBEDTLS_MD_SHA256 */ - mbedtls_pk_type_t sig_pk; /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */ - void *sig_opts; /**< Signature options to be passed to mbedtls_pk_verify_ext(), e.g. for RSASSA-PSS */ -} -mbedtls_x509_csr; - -/** - * Container for writing a CSR - */ -typedef struct mbedtls_x509write_csr -{ - mbedtls_pk_context *key; - mbedtls_asn1_named_data *subject; - mbedtls_md_type_t md_alg; - mbedtls_asn1_named_data *extensions; -} -mbedtls_x509write_csr; - -#if defined(MBEDTLS_X509_CSR_PARSE_C) -/** - * \brief Load a Certificate Signing Request (CSR) in DER format - * - * \note CSR attributes (if any) are currently silently ignored. - * - * \param csr CSR context to fill - * \param buf buffer holding the CRL data - * \param buflen size of the buffer - * - * \return 0 if successful, or a specific X509 error code - */ -int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr, - const unsigned char *buf, size_t buflen ); - -/** - * \brief Load a Certificate Signing Request (CSR), DER or PEM format - * - * \note See notes for \c mbedtls_x509_csr_parse_der() - * - * \param csr CSR context to fill - * \param buf buffer holding the CRL data - * \param buflen size of the buffer - * (including the terminating null byte for PEM data) - * - * \return 0 if successful, or a specific X509 or PEM error code - */ -int mbedtls_x509_csr_parse( mbedtls_x509_csr *csr, const unsigned char *buf, size_t buflen ); - -#if defined(MBEDTLS_FS_IO) -/** - * \brief Load a Certificate Signing Request (CSR) - * - * \note See notes for \c mbedtls_x509_csr_parse() - * - * \param csr CSR context to fill - * \param path filename to read the CSR from - * - * \return 0 if successful, or a specific X509 or PEM error code - */ -int mbedtls_x509_csr_parse_file( mbedtls_x509_csr *csr, const char *path ); -#endif /* MBEDTLS_FS_IO */ - -/** - * \brief Returns an informational string about the - * CSR. - * - * \param buf Buffer to write to - * \param size Maximum size of buffer - * \param prefix A line prefix - * \param csr The X509 CSR to represent - * - * \return The length of the string written (not including the - * terminated nul byte), or a negative error code. - */ -int mbedtls_x509_csr_info( char *buf, size_t size, const char *prefix, - const mbedtls_x509_csr *csr ); - -/** - * \brief Initialize a CSR - * - * \param csr CSR to initialize - */ -void mbedtls_x509_csr_init( mbedtls_x509_csr *csr ); - -/** - * \brief Unallocate all CSR data - * - * \param csr CSR to free - */ -void mbedtls_x509_csr_free( mbedtls_x509_csr *csr ); -#endif /* MBEDTLS_X509_CSR_PARSE_C */ - -/* \} name */ -/* \} addtogroup x509_module */ - -#if defined(MBEDTLS_X509_CSR_WRITE_C) -/** - * \brief Initialize a CSR context - * - * \param ctx CSR context to initialize - */ -void mbedtls_x509write_csr_init( mbedtls_x509write_csr *ctx ); - -/** - * \brief Set the subject name for a CSR - * Subject names should contain a comma-separated list - * of OID types and values: - * e.g. "C=UK,O=ARM,CN=mbed TLS Server 1" - * - * \param ctx CSR context to use - * \param subject_name subject name to set - * - * \return 0 if subject name was parsed successfully, or - * a specific error code - */ -int mbedtls_x509write_csr_set_subject_name( mbedtls_x509write_csr *ctx, - const char *subject_name ); - -/** - * \brief Set the key for a CSR (public key will be included, - * private key used to sign the CSR when writing it) - * - * \param ctx CSR context to use - * \param key Asymetric key to include - */ -void mbedtls_x509write_csr_set_key( mbedtls_x509write_csr *ctx, mbedtls_pk_context *key ); - -/** - * \brief Set the MD algorithm to use for the signature - * (e.g. MBEDTLS_MD_SHA1) - * - * \param ctx CSR context to use - * \param md_alg MD algorithm to use - */ -void mbedtls_x509write_csr_set_md_alg( mbedtls_x509write_csr *ctx, mbedtls_md_type_t md_alg ); - -/** - * \brief Set the Key Usage Extension flags - * (e.g. MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_KEY_CERT_SIGN) - * - * \param ctx CSR context to use - * \param key_usage key usage flags to set - * - * \return 0 if successful, or MBEDTLS_ERR_X509_ALLOC_FAILED - * - * \note The decipherOnly flag from the Key Usage - * extension is represented by bit 8 (i.e. - * 0x8000), which cannot typically be represented - * in an unsigned char. Therefore, the flag - * decipherOnly (i.e. - * #MBEDTLS_X509_KU_DECIPHER_ONLY) cannot be set using this - * function. - */ -int mbedtls_x509write_csr_set_key_usage( mbedtls_x509write_csr *ctx, unsigned char key_usage ); - -/** - * \brief Set the Netscape Cert Type flags - * (e.g. MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT | MBEDTLS_X509_NS_CERT_TYPE_EMAIL) - * - * \param ctx CSR context to use - * \param ns_cert_type Netscape Cert Type flags to set - * - * \return 0 if successful, or MBEDTLS_ERR_X509_ALLOC_FAILED - */ -int mbedtls_x509write_csr_set_ns_cert_type( mbedtls_x509write_csr *ctx, - unsigned char ns_cert_type ); - -/** - * \brief Generic function to add to or replace an extension in the - * CSR - * - * \param ctx CSR context to use - * \param oid OID of the extension - * \param oid_len length of the OID - * \param val value of the extension OCTET STRING - * \param val_len length of the value data - * - * \return 0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED - */ -int mbedtls_x509write_csr_set_extension( mbedtls_x509write_csr *ctx, - const char *oid, size_t oid_len, - const unsigned char *val, size_t val_len ); - -/** - * \brief Free the contents of a CSR context - * - * \param ctx CSR context to free - */ -void mbedtls_x509write_csr_free( mbedtls_x509write_csr *ctx ); - -/** - * \brief Write a CSR (Certificate Signing Request) to a - * DER structure - * Note: data is written at the end of the buffer! Use the - * return value to determine where you should start - * using the buffer - * - * \param ctx CSR to write away - * \param buf buffer to write to - * \param size size of the buffer - * \param f_rng RNG function (for signature, see note) - * \param p_rng RNG parameter - * - * \return length of data written if successful, or a specific - * error code - * - * \note f_rng may be NULL if RSA is used for signature and the - * signature is made offline (otherwise f_rng is desirable - * for countermeasures against timing attacks). - * ECDSA signatures always require a non-NULL f_rng. - */ -int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); - -#if defined(MBEDTLS_PEM_WRITE_C) -/** - * \brief Write a CSR (Certificate Signing Request) to a - * PEM string - * - * \param ctx CSR to write away - * \param buf buffer to write to - * \param size size of the buffer - * \param f_rng RNG function (for signature, see note) - * \param p_rng RNG parameter - * - * \return 0 if successful, or a specific error code - * - * \note f_rng may be NULL if RSA is used for signature and the - * signature is made offline (otherwise f_rng is desirable - * for countermeasures against timing attacks). - * ECDSA signatures always require a non-NULL f_rng. - */ -int mbedtls_x509write_csr_pem( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); -#endif /* MBEDTLS_PEM_WRITE_C */ -#endif /* MBEDTLS_X509_CSR_WRITE_C */ - -#ifdef __cplusplus -} -#endif - -#endif /* mbedtls_x509_csr.h */ diff --git a/library/certs.c b/library/certs.c deleted file mode 100644 index b54ff611f..000000000 --- a/library/certs.c +++ /dev/null @@ -1,436 +0,0 @@ -/* - * X.509 test certificates - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "mbedtls/certs.h" - -#if defined(MBEDTLS_CERTS_C) - -#if defined(MBEDTLS_ECDSA_C) -#define TEST_CA_CRT_EC \ -"-----BEGIN CERTIFICATE-----\r\n" \ -"MIICUjCCAdegAwIBAgIJAMFD4n5iQ8zoMAoGCCqGSM49BAMCMD4xCzAJBgNVBAYT\r\n" \ -"Ak5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBF\r\n" \ -"QyBDQTAeFw0xMzA5MjQxNTQ5NDhaFw0yMzA5MjIxNTQ5NDhaMD4xCzAJBgNVBAYT\r\n" \ -"Ak5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBF\r\n" \ -"QyBDQTB2MBAGByqGSM49AgEGBSuBBAAiA2IABMPaKzRBN1gvh1b+/Im6KUNLTuBu\r\n" \ -"ww5XUzM5WNRStJGVOQsj318XJGJI/BqVKc4sLYfCiFKAr9ZqqyHduNMcbli4yuiy\r\n" \ -"aY7zQa0pw7RfdadHb9UZKVVpmlM7ILRmFmAzHqOBoDCBnTAdBgNVHQ4EFgQUnW0g\r\n" \ -"JEkBPyvLeLUZvH4kydv7NnwwbgYDVR0jBGcwZYAUnW0gJEkBPyvLeLUZvH4kydv7\r\n" \ -"NnyhQqRAMD4xCzAJBgNVBAYTAk5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UE\r\n" \ -"AxMTUG9sYXJzc2wgVGVzdCBFQyBDQYIJAMFD4n5iQ8zoMAwGA1UdEwQFMAMBAf8w\r\n" \ -"CgYIKoZIzj0EAwIDaQAwZgIxAMO0YnNWKJUAfXgSJtJxexn4ipg+kv4znuR50v56\r\n" \ -"t4d0PCu412mUC6Nnd7izvtE2MgIxAP1nnJQjZ8BWukszFQDG48wxCCyci9qpdSMv\r\n" \ -"uCjn8pwUOkABXK8Mss90fzCfCEOtIA==\r\n" \ -"-----END CERTIFICATE-----\r\n" -const char mbedtls_test_ca_crt_ec[] = TEST_CA_CRT_EC; -const size_t mbedtls_test_ca_crt_ec_len = sizeof( mbedtls_test_ca_crt_ec ); - -const char mbedtls_test_ca_key_ec[] = -"-----BEGIN EC PRIVATE KEY-----\r\n" -"Proc-Type: 4,ENCRYPTED\r\n" -"DEK-Info: DES-EDE3-CBC,307EAB469933D64E\r\n" -"\r\n" -"IxbrRmKcAzctJqPdTQLA4SWyBYYGYJVkYEna+F7Pa5t5Yg/gKADrFKcm6B72e7DG\r\n" -"ihExtZI648s0zdYw6qSJ74vrPSuWDe5qm93BqsfVH9svtCzWHW0pm1p0KTBCFfUq\r\n" -"UsuWTITwJImcnlAs1gaRZ3sAWm7cOUidL0fo2G0fYUFNcYoCSLffCFTEHBuPnagb\r\n" -"a77x/sY1Bvii8S9/XhDTb6pTMx06wzrm\r\n" -"-----END EC PRIVATE KEY-----\r\n"; -const size_t mbedtls_test_ca_key_ec_len = sizeof( mbedtls_test_ca_key_ec ); - -const char mbedtls_test_ca_pwd_ec[] = "PolarSSLTest"; -const size_t mbedtls_test_ca_pwd_ec_len = sizeof( mbedtls_test_ca_pwd_ec ) - 1; - -const char mbedtls_test_srv_crt_ec[] = -"-----BEGIN CERTIFICATE-----\r\n" -"MIICHzCCAaWgAwIBAgIBCTAKBggqhkjOPQQDAjA+MQswCQYDVQQGEwJOTDERMA8G\r\n" -"A1UEChMIUG9sYXJTU0wxHDAaBgNVBAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0EwHhcN\r\n" -"MTMwOTI0MTU1MjA0WhcNMjMwOTIyMTU1MjA0WjA0MQswCQYDVQQGEwJOTDERMA8G\r\n" -"A1UEChMIUG9sYXJTU0wxEjAQBgNVBAMTCWxvY2FsaG9zdDBZMBMGByqGSM49AgEG\r\n" -"CCqGSM49AwEHA0IABDfMVtl2CR5acj7HWS3/IG7ufPkGkXTQrRS192giWWKSTuUA\r\n" -"2CMR/+ov0jRdXRa9iojCa3cNVc2KKg76Aci07f+jgZ0wgZowCQYDVR0TBAIwADAd\r\n" -"BgNVHQ4EFgQUUGGlj9QH2deCAQzlZX+MY0anE74wbgYDVR0jBGcwZYAUnW0gJEkB\r\n" -"PyvLeLUZvH4kydv7NnyhQqRAMD4xCzAJBgNVBAYTAk5MMREwDwYDVQQKEwhQb2xh\r\n" -"clNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBFQyBDQYIJAMFD4n5iQ8zoMAoG\r\n" -"CCqGSM49BAMCA2gAMGUCMQCaLFzXptui5WQN8LlO3ddh1hMxx6tzgLvT03MTVK2S\r\n" -"C12r0Lz3ri/moSEpNZWqPjkCMCE2f53GXcYLqyfyJR078c/xNSUU5+Xxl7VZ414V\r\n" -"fGa5kHvHARBPc8YAIVIqDvHH1Q==\r\n" -"-----END CERTIFICATE-----\r\n"; -const size_t mbedtls_test_srv_crt_ec_len = sizeof( mbedtls_test_srv_crt_ec ); - -const char mbedtls_test_srv_key_ec[] = -"-----BEGIN EC PRIVATE KEY-----\r\n" -"MHcCAQEEIPEqEyB2AnCoPL/9U/YDHvdqXYbIogTywwyp6/UfDw6noAoGCCqGSM49\r\n" -"AwEHoUQDQgAEN8xW2XYJHlpyPsdZLf8gbu58+QaRdNCtFLX3aCJZYpJO5QDYIxH/\r\n" -"6i/SNF1dFr2KiMJrdw1VzYoqDvoByLTt/w==\r\n" -"-----END EC PRIVATE KEY-----\r\n"; -const size_t mbedtls_test_srv_key_ec_len = sizeof( mbedtls_test_srv_key_ec ); - -const char mbedtls_test_cli_crt_ec[] = -"-----BEGIN CERTIFICATE-----\r\n" -"MIICLDCCAbKgAwIBAgIBDTAKBggqhkjOPQQDAjA+MQswCQYDVQQGEwJOTDERMA8G\r\n" -"A1UEChMIUG9sYXJTU0wxHDAaBgNVBAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0EwHhcN\r\n" -"MTMwOTI0MTU1MjA0WhcNMjMwOTIyMTU1MjA0WjBBMQswCQYDVQQGEwJOTDERMA8G\r\n" -"A1UEChMIUG9sYXJTU0wxHzAdBgNVBAMTFlBvbGFyU1NMIFRlc3QgQ2xpZW50IDIw\r\n" -"WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARX5a6xc9/TrLuTuIH/Eq7u5lOszlVT\r\n" -"9jQOzC7jYyUL35ji81xgNpbA1RgUcOV/n9VLRRjlsGzVXPiWj4dwo+THo4GdMIGa\r\n" -"MAkGA1UdEwQCMAAwHQYDVR0OBBYEFHoAX4Zk/OBd5REQO7LmO8QmP8/iMG4GA1Ud\r\n" -"IwRnMGWAFJ1tICRJAT8ry3i1Gbx+JMnb+zZ8oUKkQDA+MQswCQYDVQQGEwJOTDER\r\n" -"MA8GA1UEChMIUG9sYXJTU0wxHDAaBgNVBAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0GC\r\n" -"CQDBQ+J+YkPM6DAKBggqhkjOPQQDAgNoADBlAjBKZQ17IIOimbmoD/yN7o89u3BM\r\n" -"lgOsjnhw3fIOoLIWy2WOGsk/LGF++DzvrRzuNiACMQCd8iem1XS4JK7haj8xocpU\r\n" -"LwjQje5PDGHfd3h9tP38Qknu5bJqws0md2KOKHyeV0U=\r\n" -"-----END CERTIFICATE-----\r\n"; -const size_t mbedtls_test_cli_crt_ec_len = sizeof( mbedtls_test_cli_crt_ec ); - -const char mbedtls_test_cli_key_ec[] = -"-----BEGIN EC PRIVATE KEY-----\r\n" -"MHcCAQEEIPb3hmTxZ3/mZI3vyk7p3U3wBf+WIop6hDhkFzJhmLcqoAoGCCqGSM49\r\n" -"AwEHoUQDQgAEV+WusXPf06y7k7iB/xKu7uZTrM5VU/Y0Dswu42MlC9+Y4vNcYDaW\r\n" -"wNUYFHDlf5/VS0UY5bBs1Vz4lo+HcKPkxw==\r\n" -"-----END EC PRIVATE KEY-----\r\n"; -const size_t mbedtls_test_cli_key_ec_len = sizeof( mbedtls_test_cli_key_ec ); -#endif /* MBEDTLS_ECDSA_C */ - -#if defined(MBEDTLS_RSA_C) -#if defined(MBEDTLS_SHA256_C) -#define TEST_CA_CRT_RSA_SHA256 \ -"-----BEGIN CERTIFICATE-----\r\n" \ -"MIIDhzCCAm+gAwIBAgIBADANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDER\r\n" \ -"MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \ -"MTcwNTA0MTY1NzAxWhcNMjcwNTA1MTY1NzAxWjA7MQswCQYDVQQGEwJOTDERMA8G\r\n" \ -"A1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwggEiMA0G\r\n" \ -"CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDA3zf8F7vglp0/ht6WMn1EpRagzSHx\r\n" \ -"mdTs6st8GFgIlKXsm8WL3xoemTiZhx57wI053zhdcHgH057Zk+i5clHFzqMwUqny\r\n" \ -"50BwFMtEonILwuVA+T7lpg6z+exKY8C4KQB0nFc7qKUEkHHxvYPZP9al4jwqj+8n\r\n" \ -"YMPGn8u67GB9t+aEMr5P+1gmIgNb1LTV+/Xjli5wwOQuvfwu7uJBVcA0Ln0kcmnL\r\n" \ -"R7EUQIN9Z/SG9jGr8XmksrUuEvmEF/Bibyc+E1ixVA0hmnM3oTDPb5Lc9un8rNsu\r\n" \ -"KNF+AksjoBXyOGVkCeoMbo4bF6BxyLObyavpw/LPh5aPgAIynplYb6LVAgMBAAGj\r\n" \ -"gZUwgZIwHQYDVR0OBBYEFLRa5KWz3tJS9rnVppUP6z68x/3/MGMGA1UdIwRcMFqA\r\n" \ -"FLRa5KWz3tJS9rnVppUP6z68x/3/oT+kPTA7MQswCQYDVQQGEwJOTDERMA8GA1UE\r\n" \ -"CgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0GCAQAwDAYDVR0T\r\n" \ -"BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAHK/HHrTZMnnVMpde1io+voAtql7j\r\n" \ -"4sRhLrjD7o3THtwRbDa2diCvpq0Sq23Ng2LMYoXsOxoL/RQK3iN7UKxV3MKPEr0w\r\n" \ -"XQS+kKQqiT2bsfrjnWMVHZtUOMpm6FNqcdGm/Rss3vKda2lcKl8kUnq/ylc1+QbB\r\n" \ -"G6A6tUvQcr2ZyWfVg+mM5XkhTrOOXus2OLikb4WwEtJTJRNE0f+yPODSUz0/vT57\r\n" \ -"ApH0CnB80bYJshYHPHHymOtleAB8KSYtqm75g/YNobjnjB6cm4HkW3OZRVIl6fYY\r\n" \ -"n20NRVA1Vjs6GAROr4NqW4k/+LofY9y0LLDE+p0oIEKXIsIvhPr39swxSA==\r\n" \ -"-----END CERTIFICATE-----\r\n" - -static const char mbedtls_test_ca_crt_rsa_sha256[] = TEST_CA_CRT_RSA_SHA256; -const char mbedtls_test_ca_crt_rsa[] = TEST_CA_CRT_RSA_SHA256; -const size_t mbedtls_test_ca_crt_rsa_len = sizeof( mbedtls_test_ca_crt_rsa ); -#define TEST_CA_CRT_RSA_SOME -#endif /* MBEDTLS_SHA256_C */ - -#if !defined(TEST_CA_CRT_RSA_SOME) || defined(MBEDTLS_SHA1_C) -#define TEST_CA_CRT_RSA_SHA1 \ -"-----BEGIN CERTIFICATE-----\r\n" \ -"MIIDhzCCAm+gAwIBAgIBADANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n" \ -"MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \ -"MTEwMjEyMTQ0NDAwWhcNMjEwMjEyMTQ0NDAwWjA7MQswCQYDVQQGEwJOTDERMA8G\r\n" \ -"A1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwggEiMA0G\r\n" \ -"CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDA3zf8F7vglp0/ht6WMn1EpRagzSHx\r\n" \ -"mdTs6st8GFgIlKXsm8WL3xoemTiZhx57wI053zhdcHgH057Zk+i5clHFzqMwUqny\r\n" \ -"50BwFMtEonILwuVA+T7lpg6z+exKY8C4KQB0nFc7qKUEkHHxvYPZP9al4jwqj+8n\r\n" \ -"YMPGn8u67GB9t+aEMr5P+1gmIgNb1LTV+/Xjli5wwOQuvfwu7uJBVcA0Ln0kcmnL\r\n" \ -"R7EUQIN9Z/SG9jGr8XmksrUuEvmEF/Bibyc+E1ixVA0hmnM3oTDPb5Lc9un8rNsu\r\n" \ -"KNF+AksjoBXyOGVkCeoMbo4bF6BxyLObyavpw/LPh5aPgAIynplYb6LVAgMBAAGj\r\n" \ -"gZUwgZIwDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQUtFrkpbPe0lL2udWmlQ/rPrzH\r\n" \ -"/f8wYwYDVR0jBFwwWoAUtFrkpbPe0lL2udWmlQ/rPrzH/f+hP6Q9MDsxCzAJBgNV\r\n" \ -"BAYTAk5MMREwDwYDVQQKEwhQb2xhclNTTDEZMBcGA1UEAxMQUG9sYXJTU0wgVGVz\r\n" \ -"dCBDQYIBADANBgkqhkiG9w0BAQUFAAOCAQEAuP1U2ABUkIslsCfdlc2i94QHHYeJ\r\n" \ -"SsR4EdgHtdciUI5I62J6Mom+Y0dT/7a+8S6MVMCZP6C5NyNyXw1GWY/YR82XTJ8H\r\n" \ -"DBJiCTok5DbZ6SzaONBzdWHXwWwmi5vg1dxn7YxrM9d0IjxM27WNKs4sDQhZBQkF\r\n" \ -"pjmfs2cb4oPl4Y9T9meTx/lvdkRYEug61Jfn6cA+qHpyPYdTH+UshITnmp5/Ztkf\r\n" \ -"m/UTSLBNFNHesiTZeH31NcxYGdHSme9Nc/gfidRa0FLOCfWxRlFqAI47zG9jAQCZ\r\n" \ -"7Z2mCGDNMhjQc+BYcdnl0lPXjdDK6V0qCg1dVewhUBcW5gZKzV7e9+DpVA==\r\n" \ -"-----END CERTIFICATE-----\r\n" - -static const char mbedtls_test_ca_crt_rsa_sha1[] = TEST_CA_CRT_RSA_SHA1; - -#if !defined (TEST_CA_CRT_RSA_SOME) -const char mbedtls_test_ca_crt_rsa[] = TEST_CA_CRT_RSA_SHA1; -const size_t mbedtls_test_ca_crt_rsa_len = sizeof( mbedtls_test_ca_crt_rsa ); -#endif /* !TEST_CA_CRT_RSA_SOME */ -#endif /* !TEST_CA_CRT_RSA_COME || MBEDTLS_SHA1_C */ - -#if defined(MBEDTLS_SHA256_C) -/* tests/data_files/server2-sha256.crt */ -#define TEST_SRV_CRT_RSA_SHA256 \ -"-----BEGIN CERTIFICATE-----\r\n" \ -"MIIDNzCCAh+gAwIBAgIBAjANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDER\r\n" \ -"MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \ -"MTEwMjEyMTQ0NDA2WhcNMjEwMjEyMTQ0NDA2WjA0MQswCQYDVQQGEwJOTDERMA8G\r\n" \ -"A1UECgwIUG9sYXJTU0wxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcN\r\n" \ -"AQEBBQADggEPADCCAQoCggEBAMFNo93nzR3RBNdJcriZrA545Do8Ss86ExbQWuTN\r\n" \ -"owCIp+4ea5anUrSQ7y1yej4kmvy2NKwk9XfgJmSMnLAofaHa6ozmyRyWvP7BBFKz\r\n" \ -"NtSj+uGxdtiQwWG0ZlI2oiZTqqt0Xgd9GYLbKtgfoNkNHC1JZvdbJXNG6AuKT2kM\r\n" \ -"tQCQ4dqCEGZ9rlQri2V5kaHiYcPNQEkI7mgM8YuG0ka/0LiqEQMef1aoGh5EGA8P\r\n" \ -"hYvai0Re4hjGYi/HZo36Xdh98yeJKQHFkA4/J/EwyEoO79bex8cna8cFPXrEAjya\r\n" \ -"HT4P6DSYW8tzS1KW2BGiLICIaTla0w+w3lkvEcf36hIBMJcCAwEAAaNNMEswCQYD\r\n" \ -"VR0TBAIwADAdBgNVHQ4EFgQUpQXoZLjc32APUBJNYKhkr02LQ5MwHwYDVR0jBBgw\r\n" \ -"FoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8wDQYJKoZIhvcNAQELBQADggEBAGGEshT5\r\n" \ -"kvnRmLVScVeUEdwIrvW7ezbGbUvJ8VxeJ79/HSjlLiGbMc4uUathwtzEdi9R/4C5\r\n" \ -"DXBNeEPTkbB+fhG1W06iHYj/Dp8+aaG7fuDxKVKHVZSqBnmQLn73ymyclZNHii5A\r\n" \ -"3nTS8WUaHAzxN/rajOtoM7aH1P9tULpHrl+7HOeLMpxUnwI12ZqZaLIzxbcdJVcr\r\n" \ -"ra2F00aXCGkYVLvyvbZIq7LC+yVysej5gCeQYD7VFOEks0jhFjrS06gP0/XnWv6v\r\n" \ -"eBoPez9d+CCjkrhseiWzXOiriIMICX48EloO/DrsMRAtvlwq7EDz4QhILz6ffndm\r\n" \ -"e4K1cVANRPN2o9Y=\r\n" \ -"-----END CERTIFICATE-----\r\n" - -const char mbedtls_test_srv_crt_rsa[] = TEST_SRV_CRT_RSA_SHA256; -const size_t mbedtls_test_srv_crt_rsa_len = sizeof( mbedtls_test_srv_crt_rsa ); -#define TEST_SRV_CRT_RSA_SOME -#endif /* MBEDTLS_SHA256_C */ - -#if !defined(TEST_SRV_CRT_RSA_SOME) || defined(MBEDTLS_SHA1_C) -/* tests/data_files/server2.crt */ -#define TEST_SRV_CRT_RSA_SHA1 \ -"-----BEGIN CERTIFICATE-----\r\n" \ -"MIIDNzCCAh+gAwIBAgIBAjANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n" \ -"MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \ -"MTEwMjEyMTQ0NDA2WhcNMjEwMjEyMTQ0NDA2WjA0MQswCQYDVQQGEwJOTDERMA8G\r\n" \ -"A1UECgwIUG9sYXJTU0wxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcN\r\n" \ -"AQEBBQADggEPADCCAQoCggEBAMFNo93nzR3RBNdJcriZrA545Do8Ss86ExbQWuTN\r\n" \ -"owCIp+4ea5anUrSQ7y1yej4kmvy2NKwk9XfgJmSMnLAofaHa6ozmyRyWvP7BBFKz\r\n" \ -"NtSj+uGxdtiQwWG0ZlI2oiZTqqt0Xgd9GYLbKtgfoNkNHC1JZvdbJXNG6AuKT2kM\r\n" \ -"tQCQ4dqCEGZ9rlQri2V5kaHiYcPNQEkI7mgM8YuG0ka/0LiqEQMef1aoGh5EGA8P\r\n" \ -"hYvai0Re4hjGYi/HZo36Xdh98yeJKQHFkA4/J/EwyEoO79bex8cna8cFPXrEAjya\r\n" \ -"HT4P6DSYW8tzS1KW2BGiLICIaTla0w+w3lkvEcf36hIBMJcCAwEAAaNNMEswCQYD\r\n" \ -"VR0TBAIwADAdBgNVHQ4EFgQUpQXoZLjc32APUBJNYKhkr02LQ5MwHwYDVR0jBBgw\r\n" \ -"FoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8wDQYJKoZIhvcNAQEFBQADggEBAAFzC0rF\r\n" \ -"y6De8WMcdgQrEw3AhBHFjzqnxZw1ene4IBSC7lTw8rBSy3jOWQdPUWn+0y/pCeeF\r\n" \ -"kti6sevFdl1hLemGtd4q+T9TKEKGg3ND4ARfB5AUZZ9uEHq8WBkiwus5clGS17Qd\r\n" \ -"dS/TOisB59tQruLx1E1bPLtBKyqk4koC5WAULJwfpswGSyWJTpYwIpxcWE3D2tBu\r\n" \ -"UB6MZfXZFzWmWEOyKbeoXjXe8GBCGgHLywvYDsGQ36HSGtEsAvR2QaTLSxWYcfk1\r\n" \ -"fbDn4jSWkb4yZy1r01UEigFQtONieGwRFaUqEcFJHJvEEGVgh9keaVlOj2vrwf5r\r\n" \ -"4mN4lW7gLdenN6g=\r\n" \ -"-----END CERTIFICATE-----\r\n"; - -#if !defined(TEST_SRV_CRT_RSA_SOME) -const char mbedtls_test_srv_crt_rsa[] = TEST_SRV_CRT_RSA_SHA1; -const size_t mbedtls_test_srv_crt_rsa_len = sizeof( mbedtls_test_srv_crt_rsa ); -#endif /* TEST_SRV_CRT_RSA_SOME */ -#endif /* !TEST_CA_CRT_RSA_SOME || MBEDTLS_SHA1_C */ - -const char mbedtls_test_ca_key_rsa[] = -"-----BEGIN RSA PRIVATE KEY-----\r\n" -"Proc-Type: 4,ENCRYPTED\r\n" -"DEK-Info: DES-EDE3-CBC,A8A95B05D5B7206B\r\n" -"\r\n" -"9Qd9GeArejl1GDVh2lLV1bHt0cPtfbh5h/5zVpAVaFpqtSPMrElp50Rntn9et+JA\r\n" -"7VOyboR+Iy2t/HU4WvA687k3Bppe9GwKHjHhtl//8xFKwZr3Xb5yO5JUP8AUctQq\r\n" -"Nb8CLlZyuUC+52REAAthdWgsX+7dJO4yabzUcQ22Tp9JSD0hiL43BlkWYUNK3dAo\r\n" -"PZlmiptjnzVTjg1MxsBSydZinWOLBV8/JQgxSPo2yD4uEfig28qbvQ2wNIn0pnAb\r\n" -"GxnSAOazkongEGfvcjIIs+LZN9gXFhxcOh6kc4Q/c99B7QWETwLLkYgZ+z1a9VY9\r\n" -"gEU7CwCxYCD+h9hY6FPmsK0/lC4O7aeRKpYq00rPPxs6i7phiexg6ax6yTMmArQq\r\n" -"QmK3TAsJm8V/J5AWpLEV6jAFgRGymGGHnof0DXzVWZidrcZJWTNuGEX90nB3ee2w\r\n" -"PXJEFWKoD3K3aFcSLdHYr3mLGxP7H9ThQai9VsycxZKS5kwvBKQ//YMrmFfwPk8x\r\n" -"vTeY4KZMaUrveEel5tWZC94RSMKgxR6cyE1nBXyTQnDOGbfpNNgBKxyKbINWoOJU\r\n" -"WJZAwlsQn+QzCDwpri7+sV1mS3gBE6UY7aQmnmiiaC2V3Hbphxct/en5QsfDOt1X\r\n" -"JczSfpRWLlbPznZg8OQh/VgCMA58N5DjOzTIK7sJJ5r+94ZBTCpgAMbF588f0NTR\r\n" -"KCe4yrxGJR7X02M4nvD4IwOlpsQ8xQxZtOSgXv4LkxvdU9XJJKWZ/XNKJeWztxSe\r\n" -"Z1vdTc2YfsDBA2SEv33vxHx2g1vqtw8SjDRT2RaQSS0QuSaMJimdOX6mTOCBKk1J\r\n" -"9Q5mXTrER+/LnK0jEmXsBXWA5bqqVZIyahXSx4VYZ7l7w/PHiUDtDgyRhMMKi4n2\r\n" -"iQvQcWSQTjrpnlJbca1/DkpRt3YwrvJwdqb8asZU2VrNETh5x0QVefDRLFiVpif/\r\n" -"tUaeAe/P1F8OkS7OIZDs1SUbv/sD2vMbhNkUoCms3/PvNtdnvgL4F0zhaDpKCmlT\r\n" -"P8vx49E7v5CyRNmED9zZg4o3wmMqrQO93PtTug3Eu9oVx1zPQM1NVMyBa2+f29DL\r\n" -"1nuTCeXdo9+ni45xx+jAI4DCwrRdhJ9uzZyC6962H37H6D+5naNvClFR1s6li1Gb\r\n" -"nqPoiy/OBsEx9CaDGcqQBp5Wme/3XW+6z1ISOx+igwNTVCT14mHdBMbya0eIKft5\r\n" -"X+GnwtgEMyCYyyWuUct8g4RzErcY9+yW9Om5Hzpx4zOuW4NPZgPDTgK+t2RSL/Yq\r\n" -"rE1njrgeGYcVeG3f+OftH4s6fPbq7t1A5ZgUscbLMBqr9tK+OqygR4EgKBPsH6Cz\r\n" -"L6zlv/2RV0qAHvVuDJcIDIgwY5rJtINEm32rhOeFNJwZS5MNIC1czXZx5//ugX7l\r\n" -"I4sy5nbVhwSjtAk8Xg5dZbdTZ6mIrb7xqH+fdakZor1khG7bC2uIwibD3cSl2XkR\r\n" -"wN48lslbHnqqagr6Xm1nNOSVl8C/6kbJEsMpLhAezfRtGwvOucoaE+WbeUNolGde\r\n" -"P/eQiddSf0brnpiLJRh7qZrl9XuqYdpUqnoEdMAfotDOID8OtV7gt8a48ad8VPW2\r\n" -"-----END RSA PRIVATE KEY-----\r\n"; -const size_t mbedtls_test_ca_key_rsa_len = sizeof( mbedtls_test_ca_key_rsa ); - -const char mbedtls_test_ca_pwd_rsa[] = "PolarSSLTest"; -const size_t mbedtls_test_ca_pwd_rsa_len = sizeof( mbedtls_test_ca_pwd_rsa ) - 1; - -const char mbedtls_test_srv_key_rsa[] = -"-----BEGIN RSA PRIVATE KEY-----\r\n" -"MIIEpAIBAAKCAQEAwU2j3efNHdEE10lyuJmsDnjkOjxKzzoTFtBa5M2jAIin7h5r\r\n" -"lqdStJDvLXJ6PiSa/LY0rCT1d+AmZIycsCh9odrqjObJHJa8/sEEUrM21KP64bF2\r\n" -"2JDBYbRmUjaiJlOqq3ReB30Zgtsq2B+g2Q0cLUlm91slc0boC4pPaQy1AJDh2oIQ\r\n" -"Zn2uVCuLZXmRoeJhw81ASQjuaAzxi4bSRr/QuKoRAx5/VqgaHkQYDw+Fi9qLRF7i\r\n" -"GMZiL8dmjfpd2H3zJ4kpAcWQDj8n8TDISg7v1t7HxydrxwU9esQCPJodPg/oNJhb\r\n" -"y3NLUpbYEaIsgIhpOVrTD7DeWS8Rx/fqEgEwlwIDAQABAoIBAQCXR0S8EIHFGORZ\r\n" -"++AtOg6eENxD+xVs0f1IeGz57Tjo3QnXX7VBZNdj+p1ECvhCE/G7XnkgU5hLZX+G\r\n" -"Z0jkz/tqJOI0vRSdLBbipHnWouyBQ4e/A1yIJdlBtqXxJ1KE/ituHRbNc4j4kL8Z\r\n" -"/r6pvwnTI0PSx2Eqs048YdS92LT6qAv4flbNDxMn2uY7s4ycS4Q8w1JXnCeaAnYm\r\n" -"WYI5wxO+bvRELR2Mcz5DmVnL8jRyml6l6582bSv5oufReFIbyPZbQWlXgYnpu6He\r\n" -"GTc7E1zKYQGG/9+DQUl/1vQuCPqQwny0tQoX2w5tdYpdMdVm+zkLtbajzdTviJJa\r\n" -"TWzL6lt5AoGBAN86+SVeJDcmQJcv4Eq6UhtRr4QGMiQMz0Sod6ettYxYzMgxtw28\r\n" -"CIrgpozCc+UaZJLo7UxvC6an85r1b2nKPCLQFaggJ0H4Q0J/sZOhBIXaoBzWxveK\r\n" -"nupceKdVxGsFi8CDy86DBfiyFivfBj+47BbaQzPBj7C4rK7UlLjab2rDAoGBAN2u\r\n" -"AM2gchoFiu4v1HFL8D7lweEpi6ZnMJjnEu/dEgGQJFjwdpLnPbsj4c75odQ4Gz8g\r\n" -"sw9lao9VVzbusoRE/JGI4aTdO0pATXyG7eG1Qu+5Yc1YGXcCrliA2xM9xx+d7f+s\r\n" -"mPzN+WIEg5GJDYZDjAzHG5BNvi/FfM1C9dOtjv2dAoGAF0t5KmwbjWHBhcVqO4Ic\r\n" -"BVvN3BIlc1ue2YRXEDlxY5b0r8N4XceMgKmW18OHApZxfl8uPDauWZLXOgl4uepv\r\n" -"whZC3EuWrSyyICNhLY21Ah7hbIEBPF3L3ZsOwC+UErL+dXWLdB56Jgy3gZaBeW7b\r\n" -"vDrEnocJbqCm7IukhXHOBK8CgYEAwqdHB0hqyNSzIOGY7v9abzB6pUdA3BZiQvEs\r\n" -"3LjHVd4HPJ2x0N8CgrBIWOE0q8+0hSMmeE96WW/7jD3fPWwCR5zlXknxBQsfv0gP\r\n" -"3BC5PR0Qdypz+d+9zfMf625kyit4T/hzwhDveZUzHnk1Cf+IG7Q+TOEnLnWAWBED\r\n" -"ISOWmrUCgYAFEmRxgwAc/u+D6t0syCwAYh6POtscq9Y0i9GyWk89NzgC4NdwwbBH\r\n" -"4AgahOxIxXx2gxJnq3yfkJfIjwf0s2DyP0kY2y6Ua1OeomPeY9mrIS4tCuDQ6LrE\r\n" -"TB6l9VGoxJL4fyHnZb8L5gGvnB1bbD8cL6YPaDiOhcRseC9vBiEuVg==\r\n" -"-----END RSA PRIVATE KEY-----\r\n"; -const size_t mbedtls_test_srv_key_rsa_len = sizeof( mbedtls_test_srv_key_rsa ); - -/* tests/data_files/cli-rsa-sha256.crt */ -const char mbedtls_test_cli_crt_rsa[] = -"-----BEGIN CERTIFICATE-----\r\n" -"MIIDPzCCAiegAwIBAgIBBDANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDER\r\n" -"MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" -"MTEwMjEyMTQ0NDA2WhcNMjEwMjEyMTQ0NDA2WjA8MQswCQYDVQQGEwJOTDERMA8G\r\n" -"A1UECgwIUG9sYXJTU0wxGjAYBgNVBAMMEVBvbGFyU1NMIENsaWVudCAyMIIBIjAN\r\n" -"BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyHTEzLn5tXnpRdkUYLB9u5Pyax6f\r\n" -"M60Nj4o8VmXl3ETZzGaFB9X4J7BKNdBjngpuG7fa8H6r7gwQk4ZJGDTzqCrSV/Uu\r\n" -"1C93KYRhTYJQj6eVSHD1bk2y1RPD0hrt5kPqQhTrdOrA7R/UV06p86jt0uDBMHEw\r\n" -"MjDV0/YI0FZPRo7yX/k9Z5GIMC5Cst99++UMd//sMcB4j7/Cf8qtbCHWjdmLao5v\r\n" -"4Jv4EFbMs44TFeY0BGbH7vk2DmqV9gmaBmf0ZXH4yqSxJeD+PIs1BGe64E92hfx/\r\n" -"/DZrtenNLQNiTrM9AM+vdqBpVoNq0qjU51Bx5rU2BXcFbXvI5MT9TNUhXwIDAQAB\r\n" -"o00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBRxoQBzckAvVHZeM/xSj7zx3WtGITAf\r\n" -"BgNVHSMEGDAWgBS0WuSls97SUva51aaVD+s+vMf9/zANBgkqhkiG9w0BAQsFAAOC\r\n" -"AQEAlHabem2Tu69VUN7EipwnQn1dIHdgvT5i+iQHpSxY1crPnBbAeSdAXwsVEqLQ\r\n" -"gOOIAQD5VIITNuoGgo4i+4OpNh9u7ZkpRHla+/swsfrFWRRbBNP5Bcu74AGLstwU\r\n" -"zM8gIkBiyfM1Q1qDQISV9trlCG6O8vh8dp/rbI3rfzo99BOHXgFCrzXjCuW4vDsF\r\n" -"r+Dao26bX3sJ6UnEWg1H3o2x6PpUcvQ36h71/bz4TEbbUUEpe02V4QWuL+wrhHJL\r\n" -"U7o3SVE3Og7jPF8sat0a50YUWhwEFI256m02KAXLg89ueUyYKEr6rNwhcvXJpvU9\r\n" -"giIVvd0Sbjjnn7NC4VDbcXV8vw==\r\n" -"-----END CERTIFICATE-----\r\n"; -const size_t mbedtls_test_cli_crt_rsa_len = sizeof( mbedtls_test_cli_crt_rsa ); - -/* tests/data_files/cli-rsa.key */ -const char mbedtls_test_cli_key_rsa[] = -"-----BEGIN RSA PRIVATE KEY-----\r\n" -"MIIEpAIBAAKCAQEAyHTEzLn5tXnpRdkUYLB9u5Pyax6fM60Nj4o8VmXl3ETZzGaF\r\n" -"B9X4J7BKNdBjngpuG7fa8H6r7gwQk4ZJGDTzqCrSV/Uu1C93KYRhTYJQj6eVSHD1\r\n" -"bk2y1RPD0hrt5kPqQhTrdOrA7R/UV06p86jt0uDBMHEwMjDV0/YI0FZPRo7yX/k9\r\n" -"Z5GIMC5Cst99++UMd//sMcB4j7/Cf8qtbCHWjdmLao5v4Jv4EFbMs44TFeY0BGbH\r\n" -"7vk2DmqV9gmaBmf0ZXH4yqSxJeD+PIs1BGe64E92hfx//DZrtenNLQNiTrM9AM+v\r\n" -"dqBpVoNq0qjU51Bx5rU2BXcFbXvI5MT9TNUhXwIDAQABAoIBAGdNtfYDiap6bzst\r\n" -"yhCiI8m9TtrhZw4MisaEaN/ll3XSjaOG2dvV6xMZCMV+5TeXDHOAZnY18Yi18vzz\r\n" -"4Ut2TnNFzizCECYNaA2fST3WgInnxUkV3YXAyP6CNxJaCmv2aA0yFr2kFVSeaKGt\r\n" -"ymvljNp2NVkvm7Th8fBQBO7I7AXhz43k0mR7XmPgewe8ApZOG3hstkOaMvbWAvWA\r\n" -"zCZupdDjZYjOJqlA4eEA4H8/w7F83r5CugeBE8LgEREjLPiyejrU5H1fubEY+h0d\r\n" -"l5HZBJ68ybTXfQ5U9o/QKA3dd0toBEhhdRUDGzWtjvwkEQfqF1reGWj/tod/gCpf\r\n" -"DFi6X0ECgYEA4wOv/pjSC3ty6TuOvKX2rOUiBrLXXv2JSxZnMoMiWI5ipLQt+RYT\r\n" -"VPafL/m7Dn6MbwjayOkcZhBwk5CNz5A6Q4lJ64Mq/lqHznRCQQ2Mc1G8eyDF/fYL\r\n" -"Ze2pLvwP9VD5jTc2miDfw+MnvJhywRRLcemDFP8k4hQVtm8PMp3ZmNECgYEA4gz7\r\n" -"wzObR4gn8ibe617uQPZjWzUj9dUHYd+in1gwBCIrtNnaRn9I9U/Q6tegRYpii4ys\r\n" -"c176NmU+umy6XmuSKV5qD9bSpZWG2nLFnslrN15Lm3fhZxoeMNhBaEDTnLT26yoi\r\n" -"33gp0mSSWy94ZEqipms+ULF6sY1ZtFW6tpGFoy8CgYAQHhnnvJflIs2ky4q10B60\r\n" -"ZcxFp3rtDpkp0JxhFLhiizFrujMtZSjYNm5U7KkgPVHhLELEUvCmOnKTt4ap/vZ0\r\n" -"BxJNe1GZH3pW6SAvGDQpl9sG7uu/vTFP+lCxukmzxB0DrrDcvorEkKMom7ZCCRvW\r\n" -"KZsZ6YeH2Z81BauRj218kQKBgQCUV/DgKP2985xDTT79N08jUo3hTP5MVYCCuj/+\r\n" -"UeEw1TvZcx3LJby7P6Xad6a1/BqveaGyFKIfEFIaBUBItk801sDDpDaYc4gL00Xc\r\n" -"7lFuBHOZkxJYlss5QrGpuOEl9ZwUt5IrFLBdYaKqNHzNVC1pCPfb/JyH6Dr2HUxq\r\n" -"gxUwAQKBgQCcU6G2L8AG9d9c0UpOyL1tMvFe5Ttw0KjlQVdsh1MP6yigYo9DYuwu\r\n" -"bHFVW2r0dBTqegP2/KTOxKzaHfC1qf0RGDsUoJCNJrd1cwoCLG8P2EF4w3OBrKqv\r\n" -"8u4ytY0F+Vlanj5lm3TaoHSVF1+NWPyOTiwevIECGKwSxvlki4fDAA==\r\n" -"-----END RSA PRIVATE KEY-----\r\n"; -const size_t mbedtls_test_cli_key_rsa_len = sizeof( mbedtls_test_cli_key_rsa ); -#endif /* MBEDTLS_RSA_C */ - -#if defined(MBEDTLS_PEM_PARSE_C) -/* Concatenation of all available CA certificates */ -const char mbedtls_test_cas_pem[] = -#ifdef TEST_CA_CRT_RSA_SHA1 - TEST_CA_CRT_RSA_SHA1 -#endif -#ifdef TEST_CA_CRT_RSA_SHA256 - TEST_CA_CRT_RSA_SHA256 -#endif -#ifdef TEST_CA_CRT_EC - TEST_CA_CRT_EC -#endif - ""; -const size_t mbedtls_test_cas_pem_len = sizeof( mbedtls_test_cas_pem ); -#endif - -/* List of all available CA certificates */ -const char * mbedtls_test_cas[] = { -#if defined(TEST_CA_CRT_RSA_SHA1) - mbedtls_test_ca_crt_rsa_sha1, -#endif -#if defined(TEST_CA_CRT_RSA_SHA256) - mbedtls_test_ca_crt_rsa_sha256, -#endif -#if defined(MBEDTLS_ECDSA_C) - mbedtls_test_ca_crt_ec, -#endif - NULL -}; -const size_t mbedtls_test_cas_len[] = { -#if defined(TEST_CA_CRT_RSA_SHA1) - sizeof( mbedtls_test_ca_crt_rsa_sha1 ), -#endif -#if defined(TEST_CA_CRT_RSA_SHA256) - sizeof( mbedtls_test_ca_crt_rsa_sha256 ), -#endif -#if defined(MBEDTLS_ECDSA_C) - sizeof( mbedtls_test_ca_crt_ec ), -#endif - 0 -}; - -#if defined(MBEDTLS_RSA_C) -const char *mbedtls_test_ca_crt = mbedtls_test_ca_crt_rsa; /* SHA1 or SHA256 */ -const char *mbedtls_test_ca_key = mbedtls_test_ca_key_rsa; -const char *mbedtls_test_ca_pwd = mbedtls_test_ca_pwd_rsa; -const char *mbedtls_test_srv_crt = mbedtls_test_srv_crt_rsa; -const char *mbedtls_test_srv_key = mbedtls_test_srv_key_rsa; -const char *mbedtls_test_cli_crt = mbedtls_test_cli_crt_rsa; -const char *mbedtls_test_cli_key = mbedtls_test_cli_key_rsa; -const size_t mbedtls_test_ca_crt_len = sizeof( mbedtls_test_ca_crt_rsa ); -const size_t mbedtls_test_ca_key_len = sizeof( mbedtls_test_ca_key_rsa ); -const size_t mbedtls_test_ca_pwd_len = sizeof( mbedtls_test_ca_pwd_rsa ) - 1; -const size_t mbedtls_test_srv_crt_len = sizeof( mbedtls_test_srv_crt_rsa ); -const size_t mbedtls_test_srv_key_len = sizeof( mbedtls_test_srv_key_rsa ); -const size_t mbedtls_test_cli_crt_len = sizeof( mbedtls_test_cli_crt_rsa ); -const size_t mbedtls_test_cli_key_len = sizeof( mbedtls_test_cli_key_rsa ); -#else /* ! MBEDTLS_RSA_C, so MBEDTLS_ECDSA_C */ -const char *mbedtls_test_ca_crt = mbedtls_test_ca_crt_ec; -const char *mbedtls_test_ca_key = mbedtls_test_ca_key_ec; -const char *mbedtls_test_ca_pwd = mbedtls_test_ca_pwd_ec; -const char *mbedtls_test_srv_crt = mbedtls_test_srv_crt_ec; -const char *mbedtls_test_srv_key = mbedtls_test_srv_key_ec; -const char *mbedtls_test_cli_crt = mbedtls_test_cli_crt_ec; -const char *mbedtls_test_cli_key = mbedtls_test_cli_key_ec; -const size_t mbedtls_test_ca_crt_len = sizeof( mbedtls_test_ca_crt_ec ); -const size_t mbedtls_test_ca_key_len = sizeof( mbedtls_test_ca_key_ec ); -const size_t mbedtls_test_ca_pwd_len = sizeof( mbedtls_test_ca_pwd_ec ) - 1; -const size_t mbedtls_test_srv_crt_len = sizeof( mbedtls_test_srv_crt_ec ); -const size_t mbedtls_test_srv_key_len = sizeof( mbedtls_test_srv_key_ec ); -const size_t mbedtls_test_cli_crt_len = sizeof( mbedtls_test_cli_crt_ec ); -const size_t mbedtls_test_cli_key_len = sizeof( mbedtls_test_cli_key_ec ); -#endif /* MBEDTLS_RSA_C */ - -#endif /* MBEDTLS_CERTS_C */ diff --git a/library/debug.c b/library/debug.c deleted file mode 100644 index 0c46c0690..000000000 --- a/library/debug.c +++ /dev/null @@ -1,438 +0,0 @@ -/* - * Debugging routines - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_DEBUG_C) - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#define mbedtls_time_t time_t -#define mbedtls_snprintf snprintf -#define mbedtls_vsnprintf vsnprintf -#endif - -#include "mbedtls/debug.h" - -#include -#include -#include - -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - -#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 -} - -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; - - 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 < DEBUG_BUF_SIZE - 1 ) - { - 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 is is usually rare. - */ - if( ret == MBEDTLS_ERR_SSL_WANT_READ ) - return; - - mbedtls_snprintf( str, sizeof( str ), "%s() returned %d (-0x%04x)\n", - text, ret, -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 ); - - idx = 0; - 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_ECP_C) -void mbedtls_debug_print_ecp( const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const char *text, const mbedtls_ecp_point *X ) -{ - char str[DEBUG_BUF_SIZE]; - - if( NULL == ssl || - NULL == ssl->conf || - NULL == ssl->conf->f_dbg || - level > debug_threshold ) - { - return; - } - - mbedtls_snprintf( str, sizeof( str ), "%s(X)", text ); - mbedtls_debug_print_mpi( ssl, level, file, line, str, &X->X ); - - mbedtls_snprintf( str, sizeof( str ), "%s(Y)", text ); - mbedtls_debug_print_mpi( ssl, level, file, line, str, &X->Y ); -} -#endif /* MBEDTLS_ECP_C */ - -#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]; - int j, k, zeros = 1; - size_t i, n, idx = 0; - - if( NULL == ssl || - NULL == ssl->conf || - NULL == ssl->conf->f_dbg || - NULL == X || - level > debug_threshold ) - { - return; - } - - for( n = X->n - 1; n > 0; n-- ) - if( X->p[n] != 0 ) - break; - - for( j = ( sizeof(mbedtls_mpi_uint) << 3 ) - 1; j >= 0; j-- ) - if( ( ( X->p[n] >> j ) & 1 ) != 0 ) - break; - - mbedtls_snprintf( str + idx, sizeof( str ) - idx, "value of '%s' (%d bits) is:\n", - text, (int) ( ( n * ( sizeof(mbedtls_mpi_uint) << 3 ) ) + j + 1 ) ); - - debug_send_line( ssl, level, file, line, str ); - - idx = 0; - for( i = n + 1, j = 0; i > 0; i-- ) - { - if( zeros && X->p[i - 1] == 0 ) - continue; - - for( k = sizeof( mbedtls_mpi_uint ) - 1; k >= 0; k-- ) - { - if( zeros && ( ( X->p[i - 1] >> ( k << 3 ) ) & 0xFF ) == 0 ) - continue; - else - zeros = 0; - - if( j % 16 == 0 ) - { - if( j > 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) - ( X->p[i - 1] >> ( k << 3 ) ) & 0xFF ); - - j++; - } - - } - - if( zeros == 1 ) - idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, " 00" ); - - 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) -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( items[i].type == MBEDTLS_PK_DEBUG_MPI ) - mbedtls_debug_print_mpi( ssl, level, file, line, name, items[i].value ); - else -#if defined(MBEDTLS_ECP_C) - if( items[i].type == MBEDTLS_PK_DEBUG_ECP ) - mbedtls_debug_print_ecp( ssl, level, file, line, name, items[i].value ); - else -#endif - 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 = 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 */ - -#if defined(MBEDTLS_ECDH_C) -static void mbedtls_debug_printf_ecdh_internal( const mbedtls_ssl_context *ssl, - int level, const char *file, - int line, - const mbedtls_ecdh_context *ecdh, - mbedtls_debug_ecdh_attr attr ) -{ -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - const mbedtls_ecdh_context* ctx = ecdh; -#else - const mbedtls_ecdh_context_mbed* ctx = &ecdh->ctx.mbed_ecdh; -#endif - - switch( attr ) - { - case MBEDTLS_DEBUG_ECDH_Q: - mbedtls_debug_print_ecp( ssl, level, file, line, "ECDH: Q", - &ctx->Q ); - break; - case MBEDTLS_DEBUG_ECDH_QP: - mbedtls_debug_print_ecp( ssl, level, file, line, "ECDH: Qp", - &ctx->Qp ); - break; - case MBEDTLS_DEBUG_ECDH_Z: - mbedtls_debug_print_mpi( ssl, level, file, line, "ECDH: z", - &ctx->z ); - break; - default: - break; - } -} - -void mbedtls_debug_printf_ecdh( const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const mbedtls_ecdh_context *ecdh, - mbedtls_debug_ecdh_attr attr ) -{ -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - mbedtls_debug_printf_ecdh_internal( ssl, level, file, line, ecdh, attr ); -#else - switch( ecdh->var ) - { - default: - mbedtls_debug_printf_ecdh_internal( ssl, level, file, line, ecdh, - attr ); - } -#endif -} -#endif /* MBEDTLS_ECDH_C */ - -#endif /* MBEDTLS_DEBUG_C */ diff --git a/library/error.c b/library/error.c index c596f0bcc..7d7155ba0 100644 --- a/library/error.c +++ b/library/error.c @@ -137,10 +137,6 @@ #include "mbedtls/md5.h" #endif -#if defined(MBEDTLS_NET_C) -#include "mbedtls/net_sockets.h" -#endif - #if defined(MBEDTLS_OID_C) #include "mbedtls/oid.h" #endif @@ -193,18 +189,10 @@ #include "mbedtls/sha512.h" #endif -#if defined(MBEDTLS_SSL_TLS_C) -#include "mbedtls/ssl.h" -#endif - #if defined(MBEDTLS_THREADING_C) #include "mbedtls/threading.h" #endif -#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) -#include "mbedtls/x509.h" -#endif - #if defined(MBEDTLS_XTEA_C) #include "mbedtls/xtea.h" #endif @@ -410,165 +398,6 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen ) if( use_ret == -(MBEDTLS_ERR_RSA_HW_ACCEL_FAILED) ) mbedtls_snprintf( buf, buflen, "RSA - RSA hardware accelerator failed" ); #endif /* MBEDTLS_RSA_C */ - -#if defined(MBEDTLS_SSL_TLS_C) - if( use_ret == -(MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE) ) - mbedtls_snprintf( buf, buflen, "SSL - The requested feature is not available" ); - if( use_ret == -(MBEDTLS_ERR_SSL_BAD_INPUT_DATA) ) - mbedtls_snprintf( buf, buflen, "SSL - Bad input parameters to function" ); - if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_MAC) ) - mbedtls_snprintf( buf, buflen, "SSL - Verification of the message MAC failed" ); - if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_RECORD) ) - mbedtls_snprintf( buf, buflen, "SSL - An invalid SSL record was received" ); - if( use_ret == -(MBEDTLS_ERR_SSL_CONN_EOF) ) - mbedtls_snprintf( buf, buflen, "SSL - The connection indicated an EOF" ); - if( use_ret == -(MBEDTLS_ERR_SSL_UNKNOWN_CIPHER) ) - mbedtls_snprintf( buf, buflen, "SSL - An unknown cipher was received" ); - if( use_ret == -(MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN) ) - mbedtls_snprintf( buf, buflen, "SSL - The server has no ciphersuites in common with the client" ); - if( use_ret == -(MBEDTLS_ERR_SSL_NO_RNG) ) - mbedtls_snprintf( buf, buflen, "SSL - No RNG was provided to the SSL module" ); - if( use_ret == -(MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE) ) - mbedtls_snprintf( buf, buflen, "SSL - No client certification received from the client, but required by the authentication mode" ); - if( use_ret == -(MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE) ) - mbedtls_snprintf( buf, buflen, "SSL - Our own certificate(s) is/are too large to send in an SSL message" ); - if( use_ret == -(MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED) ) - mbedtls_snprintf( buf, buflen, "SSL - The own certificate is not set, but needed by the server" ); - if( use_ret == -(MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED) ) - mbedtls_snprintf( buf, buflen, "SSL - The own private key or pre-shared key is not set, but needed" ); - if( use_ret == -(MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED) ) - mbedtls_snprintf( buf, buflen, "SSL - No CA Chain is set, but required to operate" ); - if( use_ret == -(MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE) ) - mbedtls_snprintf( buf, buflen, "SSL - An unexpected message was received from our peer" ); - if( use_ret == -(MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE) ) - { - mbedtls_snprintf( buf, buflen, "SSL - A fatal alert message was received from our peer" ); - return; - } - if( use_ret == -(MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED) ) - mbedtls_snprintf( buf, buflen, "SSL - Verification of our peer failed" ); - if( use_ret == -(MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) ) - mbedtls_snprintf( buf, buflen, "SSL - The peer notified us that the connection is going to be closed" ); - if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO) ) - mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientHello handshake message failed" ); - if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO) ) - mbedtls_snprintf( buf, buflen, "SSL - Processing of the ServerHello handshake message failed" ); - if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE) ) - mbedtls_snprintf( buf, buflen, "SSL - Processing of the Certificate handshake message failed" ); - if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST) ) - mbedtls_snprintf( buf, buflen, "SSL - Processing of the CertificateRequest handshake message failed" ); - if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE) ) - mbedtls_snprintf( buf, buflen, "SSL - Processing of the ServerKeyExchange handshake message failed" ); - if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE) ) - mbedtls_snprintf( buf, buflen, "SSL - Processing of the ServerHelloDone handshake message failed" ); - if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE) ) - mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed" ); - if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP) ) - mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Read Public" ); - if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS) ) - mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Calculate Secret" ); - if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY) ) - mbedtls_snprintf( buf, buflen, "SSL - Processing of the CertificateVerify handshake message failed" ); - if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC) ) - mbedtls_snprintf( buf, buflen, "SSL - Processing of the ChangeCipherSpec handshake message failed" ); - if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_FINISHED) ) - mbedtls_snprintf( buf, buflen, "SSL - Processing of the Finished handshake message failed" ); - if( use_ret == -(MBEDTLS_ERR_SSL_ALLOC_FAILED) ) - mbedtls_snprintf( buf, buflen, "SSL - Memory allocation failed" ); - if( use_ret == -(MBEDTLS_ERR_SSL_HW_ACCEL_FAILED) ) - mbedtls_snprintf( buf, buflen, "SSL - Hardware acceleration function returned with error" ); - if( use_ret == -(MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH) ) - mbedtls_snprintf( buf, buflen, "SSL - Hardware acceleration function skipped / left alone data" ); - if( use_ret == -(MBEDTLS_ERR_SSL_COMPRESSION_FAILED) ) - mbedtls_snprintf( buf, buflen, "SSL - Processing of the compression / decompression failed" ); - if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION) ) - mbedtls_snprintf( buf, buflen, "SSL - Handshake protocol not within min/max boundaries" ); - if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET) ) - mbedtls_snprintf( buf, buflen, "SSL - Processing of the NewSessionTicket handshake message failed" ); - if( use_ret == -(MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED) ) - mbedtls_snprintf( buf, buflen, "SSL - Session ticket has expired" ); - if( use_ret == -(MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH) ) - mbedtls_snprintf( buf, buflen, "SSL - Public key type mismatch (eg, asked for RSA key exchange and presented EC key)" ); - if( use_ret == -(MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY) ) - mbedtls_snprintf( buf, buflen, "SSL - Unknown identity received (eg, PSK identity)" ); - if( use_ret == -(MBEDTLS_ERR_SSL_INTERNAL_ERROR) ) - mbedtls_snprintf( buf, buflen, "SSL - Internal error (eg, unexpected failure in lower-level module)" ); - if( use_ret == -(MBEDTLS_ERR_SSL_COUNTER_WRAPPING) ) - mbedtls_snprintf( buf, buflen, "SSL - A counter would wrap (eg, too many messages exchanged)" ); - if( use_ret == -(MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO) ) - mbedtls_snprintf( buf, buflen, "SSL - Unexpected message at ServerHello in renegotiation" ); - if( use_ret == -(MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED) ) - mbedtls_snprintf( buf, buflen, "SSL - DTLS client must retry for hello verification" ); - if( use_ret == -(MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL) ) - mbedtls_snprintf( buf, buflen, "SSL - A buffer is too small to receive or write a message" ); - if( use_ret == -(MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE) ) - mbedtls_snprintf( buf, buflen, "SSL - None of the common ciphersuites is usable (eg, no suitable certificate, see debug messages)" ); - if( use_ret == -(MBEDTLS_ERR_SSL_WANT_READ) ) - mbedtls_snprintf( buf, buflen, "SSL - No data of requested type currently available on underlying transport" ); - if( use_ret == -(MBEDTLS_ERR_SSL_WANT_WRITE) ) - mbedtls_snprintf( buf, buflen, "SSL - Connection requires a write call" ); - if( use_ret == -(MBEDTLS_ERR_SSL_TIMEOUT) ) - mbedtls_snprintf( buf, buflen, "SSL - The operation timed out" ); - if( use_ret == -(MBEDTLS_ERR_SSL_CLIENT_RECONNECT) ) - mbedtls_snprintf( buf, buflen, "SSL - The client initiated a reconnect from the same port" ); - if( use_ret == -(MBEDTLS_ERR_SSL_UNEXPECTED_RECORD) ) - mbedtls_snprintf( buf, buflen, "SSL - Record header looks valid but is not expected" ); - if( use_ret == -(MBEDTLS_ERR_SSL_NON_FATAL) ) - mbedtls_snprintf( buf, buflen, "SSL - The alert message received indicates a non-fatal error" ); - if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH) ) - mbedtls_snprintf( buf, buflen, "SSL - Couldn't set the hash for verifying CertificateVerify" ); - if( use_ret == -(MBEDTLS_ERR_SSL_CONTINUE_PROCESSING) ) - mbedtls_snprintf( buf, buflen, "SSL - Internal-only message signaling that further message-processing should be done" ); - if( use_ret == -(MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) ) - mbedtls_snprintf( buf, buflen, "SSL - The asynchronous operation is not completed yet" ); - if( use_ret == -(MBEDTLS_ERR_SSL_EARLY_MESSAGE) ) - mbedtls_snprintf( buf, buflen, "SSL - Internal-only message signaling that a message arrived early" ); - if( use_ret == -(MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) ) - mbedtls_snprintf( buf, buflen, "SSL - A cryptographic operation is in progress. Try again later" ); -#endif /* MBEDTLS_SSL_TLS_C */ - -#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) - if( use_ret == -(MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) ) - mbedtls_snprintf( buf, buflen, "X509 - Unavailable feature, e.g. RSA hashing/encryption combination" ); - if( use_ret == -(MBEDTLS_ERR_X509_UNKNOWN_OID) ) - mbedtls_snprintf( buf, buflen, "X509 - Requested OID is unknown" ); - if( use_ret == -(MBEDTLS_ERR_X509_INVALID_FORMAT) ) - mbedtls_snprintf( buf, buflen, "X509 - The CRT/CRL/CSR format is invalid, e.g. different type expected" ); - if( use_ret == -(MBEDTLS_ERR_X509_INVALID_VERSION) ) - mbedtls_snprintf( buf, buflen, "X509 - The CRT/CRL/CSR version element is invalid" ); - if( use_ret == -(MBEDTLS_ERR_X509_INVALID_SERIAL) ) - mbedtls_snprintf( buf, buflen, "X509 - The serial tag or value is invalid" ); - if( use_ret == -(MBEDTLS_ERR_X509_INVALID_ALG) ) - mbedtls_snprintf( buf, buflen, "X509 - The algorithm tag or value is invalid" ); - if( use_ret == -(MBEDTLS_ERR_X509_INVALID_NAME) ) - mbedtls_snprintf( buf, buflen, "X509 - The name tag or value is invalid" ); - if( use_ret == -(MBEDTLS_ERR_X509_INVALID_DATE) ) - mbedtls_snprintf( buf, buflen, "X509 - The date tag or value is invalid" ); - if( use_ret == -(MBEDTLS_ERR_X509_INVALID_SIGNATURE) ) - mbedtls_snprintf( buf, buflen, "X509 - The signature tag or value invalid" ); - if( use_ret == -(MBEDTLS_ERR_X509_INVALID_EXTENSIONS) ) - mbedtls_snprintf( buf, buflen, "X509 - The extension tag or value is invalid" ); - if( use_ret == -(MBEDTLS_ERR_X509_UNKNOWN_VERSION) ) - mbedtls_snprintf( buf, buflen, "X509 - CRT/CRL/CSR has an unsupported version number" ); - if( use_ret == -(MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG) ) - mbedtls_snprintf( buf, buflen, "X509 - Signature algorithm (oid) is unsupported" ); - if( use_ret == -(MBEDTLS_ERR_X509_SIG_MISMATCH) ) - mbedtls_snprintf( buf, buflen, "X509 - Signature algorithms do not match. (see \\c ::mbedtls_x509_crt sig_oid)" ); - if( use_ret == -(MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) ) - mbedtls_snprintf( buf, buflen, "X509 - Certificate verification failed, e.g. CRL, CA or signature check failed" ); - if( use_ret == -(MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT) ) - mbedtls_snprintf( buf, buflen, "X509 - Format not recognized as DER or PEM" ); - if( use_ret == -(MBEDTLS_ERR_X509_BAD_INPUT_DATA) ) - mbedtls_snprintf( buf, buflen, "X509 - Input invalid" ); - if( use_ret == -(MBEDTLS_ERR_X509_ALLOC_FAILED) ) - mbedtls_snprintf( buf, buflen, "X509 - Allocation of memory failed" ); - if( use_ret == -(MBEDTLS_ERR_X509_FILE_IO_ERROR) ) - mbedtls_snprintf( buf, buflen, "X509 - Read/write of file failed" ); - if( use_ret == -(MBEDTLS_ERR_X509_BUFFER_TOO_SMALL) ) - mbedtls_snprintf( buf, buflen, "X509 - Destination buffer is too small" ); - if( use_ret == -(MBEDTLS_ERR_X509_FATAL_ERROR) ) - mbedtls_snprintf( buf, buflen, "X509 - A fatal error occurred, eg the chain is too long or the vrfy callback failed" ); -#endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */ // END generated code if( strlen( buf ) == 0 ) @@ -790,35 +619,6 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen ) mbedtls_snprintf( buf, buflen, "MD5 - MD5 hardware accelerator failed" ); #endif /* MBEDTLS_MD5_C */ -#if defined(MBEDTLS_NET_C) - if( use_ret == -(MBEDTLS_ERR_NET_SOCKET_FAILED) ) - mbedtls_snprintf( buf, buflen, "NET - Failed to open a socket" ); - if( use_ret == -(MBEDTLS_ERR_NET_CONNECT_FAILED) ) - mbedtls_snprintf( buf, buflen, "NET - The connection to the given server / port failed" ); - if( use_ret == -(MBEDTLS_ERR_NET_BIND_FAILED) ) - mbedtls_snprintf( buf, buflen, "NET - Binding of the socket failed" ); - if( use_ret == -(MBEDTLS_ERR_NET_LISTEN_FAILED) ) - mbedtls_snprintf( buf, buflen, "NET - Could not listen on the socket" ); - if( use_ret == -(MBEDTLS_ERR_NET_ACCEPT_FAILED) ) - mbedtls_snprintf( buf, buflen, "NET - Could not accept the incoming connection" ); - if( use_ret == -(MBEDTLS_ERR_NET_RECV_FAILED) ) - mbedtls_snprintf( buf, buflen, "NET - Reading information from the socket failed" ); - if( use_ret == -(MBEDTLS_ERR_NET_SEND_FAILED) ) - mbedtls_snprintf( buf, buflen, "NET - Sending information through the socket failed" ); - if( use_ret == -(MBEDTLS_ERR_NET_CONN_RESET) ) - mbedtls_snprintf( buf, buflen, "NET - Connection was reset by peer" ); - if( use_ret == -(MBEDTLS_ERR_NET_UNKNOWN_HOST) ) - mbedtls_snprintf( buf, buflen, "NET - Failed to get an IP address for the given hostname" ); - if( use_ret == -(MBEDTLS_ERR_NET_BUFFER_TOO_SMALL) ) - mbedtls_snprintf( buf, buflen, "NET - Buffer is too small to hold the data" ); - if( use_ret == -(MBEDTLS_ERR_NET_INVALID_CONTEXT) ) - mbedtls_snprintf( buf, buflen, "NET - The context is invalid, eg because it was free()ed" ); - if( use_ret == -(MBEDTLS_ERR_NET_POLL_FAILED) ) - mbedtls_snprintf( buf, buflen, "NET - Polling the net context failed" ); - if( use_ret == -(MBEDTLS_ERR_NET_BAD_INPUT_DATA) ) - mbedtls_snprintf( buf, buflen, "NET - Input invalid" ); -#endif /* MBEDTLS_NET_C */ - #if defined(MBEDTLS_OID_C) if( use_ret == -(MBEDTLS_ERR_OID_NOT_FOUND) ) mbedtls_snprintf( buf, buflen, "OID - OID is not found" ); diff --git a/library/net_sockets.c b/library/net_sockets.c deleted file mode 100644 index 816b1303d..000000000 --- a/library/net_sockets.c +++ /dev/null @@ -1,668 +0,0 @@ -/* - * TCP/IP or UDP/IP networking functions - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -/* Enable definition of getaddrinfo() even when compiling with -std=c99. Must - * be set before config.h, which pulls in glibc's features.h indirectly. - * Harmless on other platforms. */ -#define _POSIX_C_SOURCE 200112L - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_NET_C) - -#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \ - !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \ - !defined(__HAIKU__) -#error "This module only works on Unix and Windows, see MBEDTLS_NET_C in config.h" -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#endif - -#include "mbedtls/net_sockets.h" - -#include - -#if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \ - !defined(EFI32) - -#define IS_EINTR( ret ) ( ( ret ) == WSAEINTR ) - -#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0501) -#undef _WIN32_WINNT -/* Enables getaddrinfo() & Co */ -#define _WIN32_WINNT 0x0501 -#endif - -#include - -#include -#include - -#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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define IS_EINTR( ret ) ( ( ret ) == EINTR ) - -#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 - -#include - -#include - -/* - * 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 ); -} - -/* - * 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; - 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; - } - - close( ctx->fd ); - 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 ) - { - close( ctx->fd ); - ret = MBEDTLS_ERR_NET_SOCKET_FAILED; - continue; - } - - if( bind( ctx->fd, cur->ai_addr, MSVC_INT_CAST cur->ai_addrlen ) != 0 ) - { - close( ctx->fd ); - 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 ) - { - close( ctx->fd ); - 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 non-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 *ip_len ) -{ - int ret; - int type; - - struct sockaddr_storage client_addr; - -#if defined(__socklen_t_defined) || defined(_SOCKLEN_T) || \ - defined(_SOCKLEN_T_DECLARED) || defined(__DEFINED_socklen_t) - 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; - *ip_len = sizeof( addr4->sin_addr.s_addr ); - - if( buf_size < *ip_len ) - return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL ); - - memcpy( client_ip, &addr4->sin_addr.s_addr, *ip_len ); - } - else - { - struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &client_addr; - *ip_len = sizeof( addr6->sin6_addr.s6_addr ); - - if( buf_size < *ip_len ) - return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL ); - - memcpy( client_ip, &addr6->sin6_addr.s6_addr, *ip_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; - struct timeval tv; - - fd_set read_fds; - fd_set write_fds; - - int fd = ctx->fd; - - if( fd < 0 ) - return( MBEDTLS_ERR_NET_INVALID_CONTEXT ); - -#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( fd, &read_fds ); - } - - FD_ZERO( &write_fds ); - if( rw & MBEDTLS_NET_POLL_WRITE ) - { - rw &= ~MBEDTLS_NET_POLL_WRITE; - FD_SET( 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__) ) - 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; - int fd = ((mbedtls_net_context *) ctx)->fd; - - if( fd < 0 ) - return( MBEDTLS_ERR_NET_INVALID_CONTEXT ); - - 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; - struct timeval tv; - fd_set read_fds; - int fd = ((mbedtls_net_context *) ctx)->fd; - - if( fd < 0 ) - return( MBEDTLS_ERR_NET_INVALID_CONTEXT ); - - FD_ZERO( &read_fds ); - FD_SET( 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; - int fd = ((mbedtls_net_context *) ctx)->fd; - - if( fd < 0 ) - return( MBEDTLS_ERR_NET_INVALID_CONTEXT ); - - 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 ); -} - -/* - * Gracefully close the connection - */ -void mbedtls_net_free( mbedtls_net_context *ctx ) -{ - if( ctx->fd == -1 ) - return; - - shutdown( ctx->fd, 2 ); - close( ctx->fd ); - - ctx->fd = -1; -} - -#endif /* MBEDTLS_NET_C */ diff --git a/library/pkcs11.c b/library/pkcs11.c deleted file mode 100644 index 0ea64252e..000000000 --- a/library/pkcs11.c +++ /dev/null @@ -1,240 +0,0 @@ -/** - * \file pkcs11.c - * - * \brief Wrapper for PKCS#11 library libpkcs11-helper - * - * \author Adriaan de Jong - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#include "mbedtls/pkcs11.h" - -#if defined(MBEDTLS_PKCS11_C) - -#include "mbedtls/md.h" -#include "mbedtls/oid.h" -#include "mbedtls/x509_crt.h" - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#include - -void mbedtls_pkcs11_init( mbedtls_pkcs11_context *ctx ) -{ - memset( ctx, 0, sizeof( mbedtls_pkcs11_context ) ); -} - -int mbedtls_pkcs11_x509_cert_bind( mbedtls_x509_crt *cert, pkcs11h_certificate_t pkcs11_cert ) -{ - int ret = 1; - unsigned char *cert_blob = NULL; - size_t cert_blob_size = 0; - - if( cert == NULL ) - { - ret = 2; - goto cleanup; - } - - if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, NULL, - &cert_blob_size ) != CKR_OK ) - { - ret = 3; - goto cleanup; - } - - cert_blob = mbedtls_calloc( 1, cert_blob_size ); - if( NULL == cert_blob ) - { - ret = 4; - goto cleanup; - } - - if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, cert_blob, - &cert_blob_size ) != CKR_OK ) - { - ret = 5; - goto cleanup; - } - - if( 0 != mbedtls_x509_crt_parse( cert, cert_blob, cert_blob_size ) ) - { - ret = 6; - goto cleanup; - } - - ret = 0; - -cleanup: - if( NULL != cert_blob ) - mbedtls_free( cert_blob ); - - return( ret ); -} - - -int mbedtls_pkcs11_priv_key_bind( mbedtls_pkcs11_context *priv_key, - pkcs11h_certificate_t pkcs11_cert ) -{ - int ret = 1; - mbedtls_x509_crt cert; - - mbedtls_x509_crt_init( &cert ); - - if( priv_key == NULL ) - goto cleanup; - - if( 0 != mbedtls_pkcs11_x509_cert_bind( &cert, pkcs11_cert ) ) - goto cleanup; - - priv_key->len = mbedtls_pk_get_len( &cert.pk ); - priv_key->pkcs11h_cert = pkcs11_cert; - - ret = 0; - -cleanup: - mbedtls_x509_crt_free( &cert ); - - return( ret ); -} - -void mbedtls_pkcs11_priv_key_free( mbedtls_pkcs11_context *priv_key ) -{ - if( NULL != priv_key ) - pkcs11h_certificate_freeCertificate( priv_key->pkcs11h_cert ); -} - -int mbedtls_pkcs11_decrypt( mbedtls_pkcs11_context *ctx, - int mode, size_t *olen, - const unsigned char *input, - unsigned char *output, - size_t output_max_len ) -{ - size_t input_len, output_len; - - if( NULL == ctx ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - if( MBEDTLS_RSA_PRIVATE != mode ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - output_len = input_len = ctx->len; - - if( input_len < 16 || input_len > output_max_len ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - /* Determine size of output buffer */ - if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input, - input_len, NULL, &output_len ) != CKR_OK ) - { - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - } - - if( output_len > output_max_len ) - return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE ); - - if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input, - input_len, output, &output_len ) != CKR_OK ) - { - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - } - *olen = output_len; - return( 0 ); -} - -int mbedtls_pkcs11_sign( mbedtls_pkcs11_context *ctx, - int mode, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - unsigned char *sig ) -{ - size_t sig_len = 0, asn_len = 0, oid_size = 0; - unsigned char *p = sig; - const char *oid; - - if( NULL == ctx ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - if( MBEDTLS_RSA_PRIVATE != mode ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - if( md_alg != MBEDTLS_MD_NONE ) - { - const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg ); - if( md_info == NULL ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - if( mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - - hashlen = mbedtls_md_get_size( md_info ); - asn_len = 10 + oid_size; - } - - sig_len = ctx->len; - if( hashlen > sig_len || asn_len > sig_len || - hashlen + asn_len > sig_len ) - { - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - } - - if( md_alg != MBEDTLS_MD_NONE ) - { - /* - * DigestInfo ::= SEQUENCE { - * digestAlgorithm DigestAlgorithmIdentifier, - * digest Digest } - * - * DigestAlgorithmIdentifier ::= AlgorithmIdentifier - * - * Digest ::= OCTET STRING - */ - *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED; - *p++ = (unsigned char) ( 0x08 + oid_size + hashlen ); - *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED; - *p++ = (unsigned char) ( 0x04 + oid_size ); - *p++ = MBEDTLS_ASN1_OID; - *p++ = oid_size & 0xFF; - memcpy( p, oid, oid_size ); - p += oid_size; - *p++ = MBEDTLS_ASN1_NULL; - *p++ = 0x00; - *p++ = MBEDTLS_ASN1_OCTET_STRING; - *p++ = hashlen; - } - - memcpy( p, hash, hashlen ); - - if( pkcs11h_certificate_signAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, sig, - asn_len + hashlen, sig, &sig_len ) != CKR_OK ) - { - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - } - - return( 0 ); -} - -#endif /* defined(MBEDTLS_PKCS11_C) */ diff --git a/library/ssl_cache.c b/library/ssl_cache.c deleted file mode 100644 index 62a0a2987..000000000 --- a/library/ssl_cache.c +++ /dev/null @@ -1,353 +0,0 @@ -/* - * SSL session cache implementation - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -/* - * These session callbacks use a simple chained list - * to store and retrieve the session information. - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_SSL_CACHE_C) - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#include "mbedtls/ssl_cache.h" -#include "mbedtls/ssl_internal.h" - -#include - -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 -} - -int mbedtls_ssl_cache_get( void *data, mbedtls_ssl_session *session ) -{ - int ret = 1; -#if defined(MBEDTLS_HAVE_TIME) - mbedtls_time_t t = mbedtls_time( NULL ); -#endif - mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data; - mbedtls_ssl_cache_entry *cur, *entry; - -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_lock( &cache->mutex ) != 0 ) - return( 1 ); -#endif - - cur = cache->chain; - entry = NULL; - - while( cur != NULL ) - { - entry = cur; - cur = cur->next; - -#if defined(MBEDTLS_HAVE_TIME) - if( cache->timeout != 0 && - (int) ( t - entry->timestamp ) > cache->timeout ) - continue; -#endif - - if( session->ciphersuite != entry->session.ciphersuite || - session->compression != entry->session.compression || - session->id_len != entry->session.id_len ) - continue; - - if( memcmp( session->id, entry->session.id, - entry->session.id_len ) != 0 ) - continue; - - ret = mbedtls_ssl_session_copy( session, &entry->session ); - if( ret != 0 ) - { - ret = 1; - goto exit; - } - -#if defined(MBEDTLS_X509_CRT_PARSE_C) && \ - defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - /* - * Restore peer certificate (without rest of the original chain) - */ - if( entry->peer_cert.p != NULL ) - { - /* `session->peer_cert` is NULL after the call to - * mbedtls_ssl_session_copy(), because cache entries - * have the `peer_cert` field set to NULL. */ - - if( ( session->peer_cert = mbedtls_calloc( 1, - sizeof(mbedtls_x509_crt) ) ) == NULL ) - { - ret = 1; - goto exit; - } - - mbedtls_x509_crt_init( session->peer_cert ); - if( mbedtls_x509_crt_parse( session->peer_cert, entry->peer_cert.p, - entry->peer_cert.len ) != 0 ) - { - mbedtls_free( session->peer_cert ); - session->peer_cert = NULL; - ret = 1; - goto exit; - } - } -#endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - - ret = 0; - goto exit; - } - -exit: -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_unlock( &cache->mutex ) != 0 ) - ret = 1; -#endif - - return( ret ); -} - -int mbedtls_ssl_cache_set( void *data, const mbedtls_ssl_session *session ) -{ - int ret = 1; -#if defined(MBEDTLS_HAVE_TIME) - mbedtls_time_t t = mbedtls_time( NULL ), oldest = 0; - mbedtls_ssl_cache_entry *old = NULL; -#endif - mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data; - mbedtls_ssl_cache_entry *cur, *prv; - int count = 0; - -#if defined(MBEDTLS_THREADING_C) - if( ( ret = mbedtls_mutex_lock( &cache->mutex ) ) != 0 ) - return( ret ); -#endif - - cur = cache->chain; - prv = NULL; - - while( cur != NULL ) - { - count++; - -#if defined(MBEDTLS_HAVE_TIME) - if( cache->timeout != 0 && - (int) ( t - cur->timestamp ) > cache->timeout ) - { - cur->timestamp = t; - break; /* expired, reuse this slot, update timestamp */ - } -#endif - - if( memcmp( session->id, cur->session.id, cur->session.id_len ) == 0 ) - break; /* client reconnected, keep timestamp for session id */ - -#if defined(MBEDTLS_HAVE_TIME) - if( oldest == 0 || cur->timestamp < oldest ) - { - oldest = cur->timestamp; - old = cur; - } -#endif - - prv = cur; - cur = cur->next; - } - - if( cur == NULL ) - { -#if defined(MBEDTLS_HAVE_TIME) - /* - * Reuse oldest entry if max_entries reached - */ - if( count >= cache->max_entries ) - { - if( old == NULL ) - { - ret = 1; - goto exit; - } - - cur = old; - } -#else /* MBEDTLS_HAVE_TIME */ - /* - * Reuse first entry in chain if max_entries reached, - * but move to last place - */ - if( count >= cache->max_entries ) - { - if( cache->chain == NULL ) - { - ret = 1; - goto exit; - } - - cur = cache->chain; - cache->chain = cur->next; - cur->next = NULL; - prv->next = cur; - } -#endif /* MBEDTLS_HAVE_TIME */ - else - { - /* - * max_entries not reached, create new entry - */ - cur = mbedtls_calloc( 1, sizeof(mbedtls_ssl_cache_entry) ); - if( cur == NULL ) - { - ret = 1; - goto exit; - } - - if( prv == NULL ) - cache->chain = cur; - else - prv->next = cur; - } - -#if defined(MBEDTLS_HAVE_TIME) - cur->timestamp = t; -#endif - } - -#if defined(MBEDTLS_X509_CRT_PARSE_C) && \ - defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - /* - * If we're reusing an entry, free its certificate first - */ - if( cur->peer_cert.p != NULL ) - { - mbedtls_free( cur->peer_cert.p ); - memset( &cur->peer_cert, 0, sizeof(mbedtls_x509_buf) ); - } -#endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - - /* Copy the entire session; this temporarily makes a copy of the - * X.509 CRT structure even though we only want to store the raw CRT. - * This inefficiency will go away as soon as we implement on-demand - * parsing of CRTs, in which case there's no need for the `peer_cert` - * field anymore in the first place, and we're done after this call. */ - ret = mbedtls_ssl_session_copy( &cur->session, session ); - if( ret != 0 ) - { - ret = 1; - goto exit; - } - -#if defined(MBEDTLS_X509_CRT_PARSE_C) && \ - defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - /* If present, free the X.509 structure and only store the raw CRT data. */ - if( cur->session.peer_cert != NULL ) - { - cur->peer_cert.p = - mbedtls_calloc( 1, cur->session.peer_cert->raw.len ); - if( cur->peer_cert.p == NULL ) - { - ret = 1; - goto exit; - } - - memcpy( cur->peer_cert.p, - cur->session.peer_cert->raw.p, - cur->session.peer_cert->raw.len ); - cur->peer_cert.len = session->peer_cert->raw.len; - - mbedtls_x509_crt_free( cur->session.peer_cert ); - mbedtls_free( cur->session.peer_cert ); - cur->session.peer_cert = NULL; - } -#endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - - ret = 0; - -exit: -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_unlock( &cache->mutex ) != 0 ) - ret = 1; -#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; - - mbedtls_ssl_session_free( &prv->session ); - -#if defined(MBEDTLS_X509_CRT_PARSE_C) && \ - defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - mbedtls_free( prv->peer_cert.p ); -#endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - - mbedtls_free( prv ); - } - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_free( &cache->mutex ); -#endif - cache->chain = NULL; -} - -#endif /* MBEDTLS_SSL_CACHE_C */ diff --git a/library/ssl_ciphersuites.c b/library/ssl_ciphersuites.c deleted file mode 100644 index 518f7dde0..000000000 --- a/library/ssl_ciphersuites.c +++ /dev/null @@ -1,2373 +0,0 @@ -/** - * \file ssl_ciphersuites.c - * - * \brief SSL ciphersuites for mbed TLS - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_SSL_TLS_C) - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#endif - -#include "mbedtls/ssl_ciphersuites.h" -#include "mbedtls/ssl.h" - -#include - -/* - * Ordered from most preferred to least preferred in terms of security. - * - * Current rule (except RC4 and 3DES, 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 - /* Chacha-Poly ephemeral suites */ - MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, - MBEDTLS_TLS_DHE_RSA_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_DHE_RSA_WITH_AES_256_GCM_SHA384, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, - MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, - MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, - MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, - MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, - MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, - MBEDTLS_TLS_DHE_RSA_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_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, - MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384, - MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, - MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, - - /* 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_DHE_RSA_WITH_ARIA_256_GCM_SHA384, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384, - MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384, - MBEDTLS_TLS_DHE_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_DHE_RSA_WITH_AES_128_GCM_SHA256, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, - MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, - MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, - MBEDTLS_TLS_DHE_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_DHE_RSA_WITH_AES_128_CBC_SHA, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, - MBEDTLS_TLS_DHE_RSA_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_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, - MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, - MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, - MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, - - /* 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_DHE_RSA_WITH_ARIA_128_GCM_SHA256, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256, - MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256, - MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256, - - /* The PSK ephemeral suites */ - MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, - MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256, - MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, - MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM, - MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, - MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, - MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, - MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA, - MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384, - MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, - MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, - MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8, - MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384, - MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384, - MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384, - - MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, - MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM, - MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, - MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, - MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, - MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA, - MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256, - MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, - MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, - MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8, - MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256, - MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256, - MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256, - - /* The ECJPAKE suite */ - MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8, - - /* All AES-256 suites */ - MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384, - MBEDTLS_TLS_RSA_WITH_AES_256_CCM, - MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256, - MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA, - MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, - MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, - MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, - MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, - MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, - MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, - MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8, - - /* All CAMELLIA-256 suites */ - MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384, - MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256, - MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, - MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384, - MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384, - MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, - MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, - - /* All ARIA-256 suites */ - MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384, - MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384, - MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384, - MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384, - MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384, - MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384, - - /* All AES-128 suites */ - MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256, - MBEDTLS_TLS_RSA_WITH_AES_128_CCM, - MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256, - MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA, - MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, - MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, - MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, - MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, - MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, - MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, - MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8, - - /* All CAMELLIA-128 suites */ - MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256, - MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256, - MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, - MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256, - MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256, - MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, - MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, - - /* All ARIA-128 suites */ - MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256, - MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256, - MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256, - MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256, - MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256, - MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256, - - /* The RSA PSK suites */ - MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256, - MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, - MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, - MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA, - MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384, - MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384, - MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384, - MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384, - - MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256, - MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, - MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA, - MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256, - MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256, - MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256, - MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256, - - /* 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, - - /* 3DES suites */ - MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, - MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, - MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, - MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA, - MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, - MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA, - MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, - MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, - MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, - MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA, - - /* RC4 suites */ - MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, - MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA, - MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA, - MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA, - MBEDTLS_TLS_RSA_WITH_RC4_128_SHA, - MBEDTLS_TLS_RSA_WITH_RC4_128_MD5, - MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA, - MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA, - MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA, - MBEDTLS_TLS_PSK_WITH_RC4_128_SHA, - - /* Weak suites */ - MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA, - MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA, - - /* 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_DHE_PSK_WITH_NULL_SHA384, - MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256, - MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA, - - MBEDTLS_TLS_RSA_WITH_NULL_SHA256, - MBEDTLS_TLS_RSA_WITH_NULL_SHA, - MBEDTLS_TLS_RSA_WITH_NULL_MD5, - MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA, - MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA, - MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384, - MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256, - MBEDTLS_TLS_RSA_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_CHACHAPOLY_C) && \ - defined(MBEDTLS_SHA256_C) && \ - 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) - { MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, - "TLS-DHE-RSA-WITH-CHACHA20-POLY1305-SHA256", - MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256, - MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) - { MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256, - "TLS-DHE-PSK-WITH-CHACHA20-POLY1305-SHA256", - MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256, - MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) - { MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256, - "TLS-RSA-PSK-WITH-CHACHA20-POLY1305-SHA256", - MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256, - MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#endif /* MBEDTLS_CHACHAPOLY_C && - MBEDTLS_SHA256_C && - MBEDTLS_SSL_PROTO_TLS1_2 */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) -#if defined(MBEDTLS_AES_C) -#if defined(MBEDTLS_SHA1_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_SHA1_C */ -#if defined(MBEDTLS_SHA256_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#if defined(MBEDTLS_GCM_C) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_GCM_C */ -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA512_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#if defined(MBEDTLS_GCM_C) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_GCM_C */ -#endif /* MBEDTLS_SHA512_C */ -#if defined(MBEDTLS_CCM_C) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - { 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_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_SHORT_TAG }, - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - { 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_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_SHORT_TAG }, -#endif /* MBEDTLS_CCM_C */ -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_CAMELLIA_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA256_C) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA512_C) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_GCM_C) -#if defined(MBEDTLS_SHA256_C) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA512_C) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_GCM_C */ -#endif /* MBEDTLS_CAMELLIA_C */ - -#if defined(MBEDTLS_DES_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDHE-ECDSA-WITH-3DES-EDE-CBC-SHA", - MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_ARC4_C) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, "TLS-ECDHE-ECDSA-WITH-RC4-128-SHA", - MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_NODTLS }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_ARC4_C */ - -#if defined(MBEDTLS_CIPHER_NULL_CIPHER) -#if defined(MBEDTLS_SHA1_C) - { 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_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) -#if defined(MBEDTLS_AES_C) -#if defined(MBEDTLS_SHA1_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_SHA1_C */ -#if defined(MBEDTLS_SHA256_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#if defined(MBEDTLS_GCM_C) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_GCM_C */ -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA512_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#if defined(MBEDTLS_GCM_C) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_GCM_C */ -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_CAMELLIA_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA256_C) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA512_C) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_GCM_C) -#if defined(MBEDTLS_SHA256_C) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA512_C) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_GCM_C */ -#endif /* MBEDTLS_CAMELLIA_C */ - -#if defined(MBEDTLS_DES_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDHE-RSA-WITH-3DES-EDE-CBC-SHA", - MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_ARC4_C) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA, "TLS-ECDHE-RSA-WITH-RC4-128-SHA", - MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_NODTLS }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_ARC4_C */ - -#if defined(MBEDTLS_CIPHER_NULL_CIPHER) -#if defined(MBEDTLS_SHA1_C) - { 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_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) -#if defined(MBEDTLS_AES_C) -#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_GCM_C) - { MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, "TLS-DHE-RSA-WITH-AES-256-GCM-SHA384", - MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C && MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_SHA256_C) -#if defined(MBEDTLS_GCM_C) - { MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, "TLS-DHE-RSA-WITH-AES-128-GCM-SHA256", - MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, "TLS-DHE-RSA-WITH-AES-128-CBC-SHA256", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - - { MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, "TLS-DHE-RSA-WITH-AES-256-CBC-SHA256", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, "TLS-DHE-RSA-WITH-AES-128-CBC-SHA", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - - { MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, "TLS-DHE-RSA-WITH-AES-256-CBC-SHA", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#if defined(MBEDTLS_CCM_C) - { MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM, "TLS-DHE-RSA-WITH-AES-256-CCM", - MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - { MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8, "TLS-DHE-RSA-WITH-AES-256-CCM-8", - MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_SHORT_TAG }, - { MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM, "TLS-DHE-RSA-WITH-AES-128-CCM", - MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - { MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8, "TLS-DHE-RSA-WITH-AES-128-CCM-8", - MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_SHORT_TAG }, -#endif /* MBEDTLS_CCM_C */ -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_CAMELLIA_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - - { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA256", - MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA", - MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - - { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA", - MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#if defined(MBEDTLS_GCM_C) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-DHE-RSA-WITH-CAMELLIA-128-GCM-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-DHE-RSA-WITH-CAMELLIA-256-GCM-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_GCM_C */ -#endif /* MBEDTLS_CAMELLIA_C */ - -#if defined(MBEDTLS_DES_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA", - MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_DES_C */ -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) -#if defined(MBEDTLS_AES_C) -#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_GCM_C) - { MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384, "TLS-RSA-WITH-AES-256-GCM-SHA384", - MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C && MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_SHA256_C) -#if defined(MBEDTLS_GCM_C) - { MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256, "TLS-RSA-WITH-AES-128-GCM-SHA256", - MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256, "TLS-RSA-WITH-AES-128-CBC-SHA256", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - - { MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256, "TLS-RSA-WITH-AES-256-CBC-SHA256", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA1_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA, "TLS-RSA-WITH-AES-128-CBC-SHA", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - - { MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA, "TLS-RSA-WITH-AES-256-CBC-SHA", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_SHA1_C */ -#if defined(MBEDTLS_CCM_C) - { MBEDTLS_TLS_RSA_WITH_AES_256_CCM, "TLS-RSA-WITH-AES-256-CCM", - MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - { MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8, "TLS-RSA-WITH-AES-256-CCM-8", - MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_SHORT_TAG }, - { MBEDTLS_TLS_RSA_WITH_AES_128_CCM, "TLS-RSA-WITH-AES-128-CCM", - MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - { MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8, "TLS-RSA-WITH-AES-128-CCM-8", - MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_SHORT_TAG }, -#endif /* MBEDTLS_CCM_C */ -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_CAMELLIA_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - - { MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256, "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA256", - MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA", - MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - - { MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA", - MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_GCM_C) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-RSA-WITH-CAMELLIA-128-GCM-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-RSA-WITH-CAMELLIA-256-GCM-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_GCM_C */ -#endif /* MBEDTLS_CAMELLIA_C */ - -#if defined(MBEDTLS_DES_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-RSA-WITH-3DES-EDE-CBC-SHA", - MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_ARC4_C) -#if defined(MBEDTLS_MD5_C) - { MBEDTLS_TLS_RSA_WITH_RC4_128_MD5, "TLS-RSA-WITH-RC4-128-MD5", - MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_MD5, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_NODTLS }, -#endif - -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_RSA_WITH_RC4_128_SHA, "TLS-RSA-WITH-RC4-128-SHA", - MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_NODTLS }, -#endif -#endif /* MBEDTLS_ARC4_C */ -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) -#if defined(MBEDTLS_AES_C) -#if defined(MBEDTLS_SHA1_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, "TLS-ECDH-RSA-WITH-AES-128-CBC-SHA", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - { MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_SHA1_C */ -#if defined(MBEDTLS_SHA256_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, "TLS-ECDH-RSA-WITH-AES-128-CBC-SHA256", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#if defined(MBEDTLS_GCM_C) - { MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, "TLS-ECDH-RSA-WITH-AES-128-GCM-SHA256", - MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_GCM_C */ -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA512_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA384", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#if defined(MBEDTLS_GCM_C) - { MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, "TLS-ECDH-RSA-WITH-AES-256-GCM-SHA384", - MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_GCM_C */ -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_CAMELLIA_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDH-RSA-WITH-CAMELLIA-128-CBC-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDH-RSA-WITH-CAMELLIA-256-CBC-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_GCM_C) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-ECDH-RSA-WITH-CAMELLIA-128-GCM-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDH-RSA-WITH-CAMELLIA-256-GCM-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_GCM_C */ -#endif /* MBEDTLS_CAMELLIA_C */ - -#if defined(MBEDTLS_DES_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDH-RSA-WITH-3DES-EDE-CBC-SHA", - MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_ARC4_C) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA, "TLS-ECDH-RSA-WITH-RC4-128-SHA", - MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_NODTLS }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_ARC4_C */ - -#if defined(MBEDTLS_CIPHER_NULL_CIPHER) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA, "TLS-ECDH-RSA-WITH-NULL-SHA", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ -#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) -#if defined(MBEDTLS_AES_C) -#if defined(MBEDTLS_SHA1_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, "TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_SHA1_C */ -#if defined(MBEDTLS_SHA256_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, "TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA256", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#if defined(MBEDTLS_GCM_C) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, "TLS-ECDH-ECDSA-WITH-AES-128-GCM-SHA256", - MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_GCM_C */ -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA512_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA384", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#if defined(MBEDTLS_GCM_C) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, "TLS-ECDH-ECDSA-WITH-AES-256-GCM-SHA384", - MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_GCM_C */ -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_CAMELLIA_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDH-ECDSA-WITH-CAMELLIA-128-CBC-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_GCM_C) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-ECDH-ECDSA-WITH-CAMELLIA-128-GCM-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDH-ECDSA-WITH-CAMELLIA-256-GCM-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_GCM_C */ -#endif /* MBEDTLS_CAMELLIA_C */ - -#if defined(MBEDTLS_DES_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDH-ECDSA-WITH-3DES-EDE-CBC-SHA", - MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_ARC4_C) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA, "TLS-ECDH-ECDSA-WITH-RC4-128-SHA", - MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_NODTLS }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_ARC4_C */ - -#if defined(MBEDTLS_CIPHER_NULL_CIPHER) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA, "TLS-ECDH-ECDSA-WITH-NULL-SHA", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ -#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) -#if defined(MBEDTLS_AES_C) -#if defined(MBEDTLS_GCM_C) -#if defined(MBEDTLS_SHA256_C) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA256_C) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ - -#if defined(MBEDTLS_SHA1_C) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#if defined(MBEDTLS_CCM_C) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - { 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_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_SHORT_TAG }, - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - { 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_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_SHORT_TAG }, -#endif /* MBEDTLS_CCM_C */ -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_CAMELLIA_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA256_C) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_GCM_C) -#if defined(MBEDTLS_SHA256_C) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_GCM_C */ -#endif /* MBEDTLS_CAMELLIA_C */ - -#if defined(MBEDTLS_DES_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-PSK-WITH-3DES-EDE-CBC-SHA", - MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_ARC4_C) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_PSK_WITH_RC4_128_SHA, "TLS-PSK-WITH-RC4-128-SHA", - MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_NODTLS }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_ARC4_C */ -#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) -#if defined(MBEDTLS_AES_C) -#if defined(MBEDTLS_GCM_C) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, "TLS-DHE-PSK-WITH-AES-128-GCM-SHA256", - MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, "TLS-DHE-PSK-WITH-AES-256-GCM-SHA384", - MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, "TLS-DHE-PSK-WITH-AES-128-CBC-SHA256", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, "TLS-DHE-PSK-WITH-AES-256-CBC-SHA384", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ - -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA, "TLS-DHE-PSK-WITH-AES-128-CBC-SHA", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - - { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA, "TLS-DHE-PSK-WITH-AES-256-CBC-SHA", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#if defined(MBEDTLS_CCM_C) - { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM, "TLS-DHE-PSK-WITH-AES-256-CCM", - MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8, "TLS-DHE-PSK-WITH-AES-256-CCM-8", - MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_SHORT_TAG }, - { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM, "TLS-DHE-PSK-WITH-AES-128-CCM", - MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8, "TLS-DHE-PSK-WITH-AES-128-CCM-8", - MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_SHORT_TAG }, -#endif /* MBEDTLS_CCM_C */ -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_CAMELLIA_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-DHE-PSK-WITH-CAMELLIA-128-CBC-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-DHE-PSK-WITH-CAMELLIA-256-CBC-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_GCM_C) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256, "TLS-DHE-PSK-WITH-CAMELLIA-128-GCM-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384, "TLS-DHE-PSK-WITH-CAMELLIA-256-GCM-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_GCM_C */ -#endif /* MBEDTLS_CAMELLIA_C */ - -#if defined(MBEDTLS_DES_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-DHE-PSK-WITH-3DES-EDE-CBC-SHA", - MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_ARC4_C) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA, "TLS-DHE-PSK-WITH-RC4-128-SHA", - MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_NODTLS }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_ARC4_C */ -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) -#if defined(MBEDTLS_AES_C) - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA256_C) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ - -#if defined(MBEDTLS_SHA1_C) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_CAMELLIA_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA256_C) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_CAMELLIA_C */ - -#if defined(MBEDTLS_DES_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-ECDHE-PSK-WITH-3DES-EDE-CBC-SHA", - MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_ARC4_C) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA, "TLS-ECDHE-PSK-WITH-RC4-128-SHA", - MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_NODTLS }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_ARC4_C */ -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) -#if defined(MBEDTLS_AES_C) -#if defined(MBEDTLS_GCM_C) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256, "TLS-RSA-PSK-WITH-AES-128-GCM-SHA256", - MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, "TLS-RSA-PSK-WITH-AES-256-GCM-SHA384", - MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, "TLS-RSA-PSK-WITH-AES-128-CBC-SHA256", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, "TLS-RSA-PSK-WITH-AES-256-CBC-SHA384", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ - -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA, "TLS-RSA-PSK-WITH-AES-128-CBC-SHA", - MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, - - { MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA, "TLS-RSA-PSK-WITH-AES-256-CBC-SHA", - MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_CAMELLIA_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-RSA-PSK-WITH-CAMELLIA-128-CBC-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-RSA-PSK-WITH-CAMELLIA-256-CBC-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_GCM_C) -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256, "TLS-RSA-PSK-WITH-CAMELLIA-128-GCM-SHA256", - MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384, "TLS-RSA-PSK-WITH-CAMELLIA-256-GCM-SHA384", - MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_GCM_C */ -#endif /* MBEDTLS_CAMELLIA_C */ - -#if defined(MBEDTLS_DES_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-RSA-PSK-WITH-3DES-EDE-CBC-SHA", - MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_ARC4_C) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA, "TLS-RSA-PSK-WITH-RC4-128-SHA", - MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_NODTLS }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_ARC4_C */ -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -#if defined(MBEDTLS_AES_C) -#if defined(MBEDTLS_CCM_C) - { 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_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_SHORT_TAG }, -#endif /* MBEDTLS_CCM_C */ -#endif /* MBEDTLS_AES_C */ -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_ENABLE_WEAK_CIPHERSUITES) -#if defined(MBEDTLS_CIPHER_NULL_CIPHER) -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) -#if defined(MBEDTLS_MD5_C) - { MBEDTLS_TLS_RSA_WITH_NULL_MD5, "TLS-RSA-WITH-NULL-MD5", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_MD5, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif - -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_RSA_WITH_NULL_SHA, "TLS-RSA-WITH-NULL-SHA", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif - -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_RSA_WITH_NULL_SHA256, "TLS-RSA-WITH-NULL-SHA256", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_PSK_WITH_NULL_SHA, "TLS-PSK-WITH-NULL-SHA", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif /* MBEDTLS_SHA1_C */ - -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_PSK_WITH_NULL_SHA256, "TLS-PSK-WITH-NULL-SHA256", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif - -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_PSK_WITH_NULL_SHA384, "TLS-PSK-WITH-NULL-SHA384", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif -#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA, "TLS-DHE-PSK-WITH-NULL-SHA", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif /* MBEDTLS_SHA1_C */ - -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256, "TLS-DHE-PSK-WITH-NULL-SHA256", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif - -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384, "TLS-DHE-PSK-WITH-NULL-SHA384", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) -#if defined(MBEDTLS_SHA1_C) - { 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_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif /* MBEDTLS_SHA1_C */ - -#if defined(MBEDTLS_SHA256_C) - { 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_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif - -#if defined(MBEDTLS_SHA512_C) - { 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_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA, "TLS-RSA-PSK-WITH-NULL-SHA", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif /* MBEDTLS_SHA1_C */ - -#if defined(MBEDTLS_SHA256_C) - { MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256, "TLS-RSA-PSK-WITH-NULL-SHA256", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif - -#if defined(MBEDTLS_SHA512_C) - { MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384, "TLS-RSA-PSK-WITH-NULL-SHA384", - MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ -#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ - -#if defined(MBEDTLS_DES_C) -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA, "TLS-DHE-RSA-WITH-DES-CBC-SHA", - MBEDTLS_CIPHER_DES_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) -#if defined(MBEDTLS_SHA1_C) - { MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA, "TLS-RSA-WITH-DES-CBC-SHA", - MBEDTLS_CIPHER_DES_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_CIPHERSUITE_WEAK }, -#endif /* MBEDTLS_SHA1_C */ -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_DES_C */ -#endif /* MBEDTLS_ENABLE_WEAK_CIPHERSUITES */ - -#if defined(MBEDTLS_ARIA_C) - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) - -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C)) - { MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384, - "TLS-RSA-WITH-ARIA-256-GCM-SHA384", - MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C)) - { MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384, - "TLS-RSA-WITH-ARIA-256-CBC-SHA384", - MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C)) - { MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256, - "TLS-RSA-WITH-ARIA-128-GCM-SHA256", - MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C)) - { MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256, - "TLS-RSA-WITH-ARIA-128-CBC-SHA256", - MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif - -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) - -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C)) - { MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384, - "TLS-RSA-PSK-WITH-ARIA-256-GCM-SHA384", - MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C)) - { MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384, - "TLS-RSA-PSK-WITH-ARIA-256-CBC-SHA384", - MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C)) - { MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256, - "TLS-RSA-PSK-WITH-ARIA-128-GCM-SHA256", - MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C)) - { MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256, - "TLS-RSA-PSK-WITH-ARIA-128-CBC-SHA256", - MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif - -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) - -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C)) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C)) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C)) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C)) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif - -#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) - -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C)) - { MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384, - "TLS-ECDH-RSA-WITH-ARIA-256-GCM-SHA384", - MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C)) - { MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384, - "TLS-ECDH-RSA-WITH-ARIA-256-CBC-SHA384", - MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C)) - { MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256, - "TLS-ECDH-RSA-WITH-ARIA-128-GCM-SHA256", - MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C)) - { MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256, - "TLS-ECDH-RSA-WITH-ARIA-128-CBC-SHA256", - MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif - -#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) - -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C)) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C)) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C)) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C)) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif - -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) - -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C)) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C)) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif - -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) - -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C)) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C)) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C)) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C)) - { 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, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif - -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) - -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C)) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384, - "TLS-ECDH-ECDSA-WITH-ARIA-256-GCM-SHA384", - MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C)) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384, - "TLS-ECDH-ECDSA-WITH-ARIA-256-CBC-SHA384", - MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C)) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256, - "TLS-ECDH-ECDSA-WITH-ARIA-128-GCM-SHA256", - MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C)) - { MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256, - "TLS-ECDH-ECDSA-WITH-ARIA-128-CBC-SHA256", - MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif - -#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) - -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C)) - { MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384, - "TLS-DHE-RSA-WITH-ARIA-256-GCM-SHA384", - MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C)) - { MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384, - "TLS-DHE-RSA-WITH-ARIA-256-CBC-SHA384", - MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C)) - { MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256, - "TLS-DHE-RSA-WITH-ARIA-128-GCM-SHA256", - MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C)) - { MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256, - "TLS-DHE-RSA-WITH-ARIA-128-CBC-SHA256", - MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif - -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) - -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C)) - { MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384, - "TLS-DHE-PSK-WITH-ARIA-256-GCM-SHA384", - MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C)) - { MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384, - "TLS-DHE-PSK-WITH-ARIA-256-CBC-SHA384", - MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C)) - { MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256, - "TLS-DHE-PSK-WITH-ARIA-128-GCM-SHA256", - MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif -#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C)) - { MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256, - "TLS-DHE-PSK-WITH-ARIA-128-CBC-SHA256", - MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, - 0 }, -#endif - -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ - -#endif /* MBEDTLS_ARIA_C */ - - - { 0, "", - MBEDTLS_CIPHER_NONE, MBEDTLS_MD_NONE, MBEDTLS_KEY_EXCHANGE_NONE, - 0, 0, 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; - -static int ciphersuite_is_removed( const mbedtls_ssl_ciphersuite_t *cs_info ) -{ - (void)cs_info; - -#if defined(MBEDTLS_REMOVE_ARC4_CIPHERSUITES) - if( cs_info->cipher == MBEDTLS_CIPHER_ARC4_128 ) - return( 1 ); -#endif /* MBEDTLS_REMOVE_ARC4_CIPHERSUITES */ - -#if defined(MBEDTLS_REMOVE_3DES_CIPHERSUITES) - if( cs_info->cipher == MBEDTLS_CIPHER_DES_EDE3_ECB || - cs_info->cipher == MBEDTLS_CIPHER_DES_EDE3_CBC ) - { - return( 1 ); - } -#endif /* MBEDTLS_REMOVE_3DES_CIPHERSUITES */ - - 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 ); -} - -#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_RSA: - case MBEDTLS_KEY_EXCHANGE_DHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: - case MBEDTLS_KEY_EXCHANGE_RSA_PSK: - return( MBEDTLS_PK_RSA ); - - case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: - return( MBEDTLS_PK_ECDSA ); - - case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: - return( MBEDTLS_PK_ECKEY ); - - default: - return( MBEDTLS_PK_NONE ); - } -} - -mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_alg( const mbedtls_ssl_ciphersuite_t *info ) -{ - switch( info->key_exchange ) - { - case MBEDTLS_KEY_EXCHANGE_RSA: - case MBEDTLS_KEY_EXCHANGE_DHE_RSA: - 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_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - 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_ECDH_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: - case MBEDTLS_KEY_EXCHANGE_ECJPAKE: - return( 1 ); - - default: - return( 0 ); - } -} -#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || 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_RSA_PSK: - case MBEDTLS_KEY_EXCHANGE_DHE_PSK: - case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK: - return( 1 ); - - default: - return( 0 ); - } -} -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ - -#endif /* MBEDTLS_SSL_TLS_C */ diff --git a/library/ssl_cli.c b/library/ssl_cli.c deleted file mode 100644 index 4e5b3a602..000000000 --- a/library/ssl_cli.c +++ /dev/null @@ -1,3944 +0,0 @@ -/* - * SSLv3/TLSv1 client-side functions - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_SSL_CLI_C) - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#include "mbedtls/debug.h" -#include "mbedtls/ssl.h" -#include "mbedtls/ssl_internal.h" - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "mbedtls/psa_util.h" -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#include - -#include - -#if defined(MBEDTLS_HAVE_TIME) -#include "mbedtls/platform_time.h" -#endif - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) -#include "mbedtls/platform_util.h" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) -static int ssl_conf_has_static_psk( mbedtls_ssl_config const *conf ) -{ - if( conf->psk_identity == NULL || - conf->psk_identity_len == 0 ) - { - return( 0 ); - } - - if( conf->psk != NULL && conf->psk_len != 0 ) - return( 1 ); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if( conf->psk_opaque != 0 ) - return( 1 ); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - return( 0 ); -} - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -static int ssl_conf_has_static_raw_psk( mbedtls_ssl_config const *conf ) -{ - if( conf->psk_identity == NULL || - conf->psk_identity_len == 0 ) - { - return( 0 ); - } - - if( conf->psk != NULL && conf->psk_len != 0 ) - return( 1 ); - - return( 0 ); -} -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) -static void ssl_write_hostname_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen ) -{ - unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; - size_t hostname_len; - - *olen = 0; - - if( ssl->hostname == NULL ) - return; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding server name extension: %s", - ssl->hostname ) ); - - hostname_len = strlen( ssl->hostname ); - - if( end < p || (size_t)( end - p ) < hostname_len + 9 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); - return; - } - - /* - * Sect. 3, RFC 6066 (TLS Extensions Definitions) - * - * In order to provide any of the server names, clients MAY include an - * extension of type "server_name" in the (extended) client hello. The - * "extension_data" field of this extension SHALL contain - * "ServerNameList" where: - * - * struct { - * NameType name_type; - * select (name_type) { - * case host_name: HostName; - * } name; - * } ServerName; - * - * enum { - * host_name(0), (255) - * } NameType; - * - * opaque HostName<1..2^16-1>; - * - * struct { - * ServerName server_name_list<1..2^16-1> - * } ServerNameList; - * - */ - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME ) & 0xFF ); - - *p++ = (unsigned char)( ( (hostname_len + 5) >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( (hostname_len + 5) ) & 0xFF ); - - *p++ = (unsigned char)( ( (hostname_len + 3) >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( (hostname_len + 3) ) & 0xFF ); - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME ) & 0xFF ); - *p++ = (unsigned char)( ( hostname_len >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( hostname_len ) & 0xFF ); - - memcpy( p, ssl->hostname, hostname_len ); - - *olen = hostname_len + 9; -} -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ - -#if defined(MBEDTLS_SSL_RENEGOTIATION) -static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen ) -{ - unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; - - *olen = 0; - - /* We're always including an TLS_EMPTY_RENEGOTIATION_INFO_SCSV in the - * initial ClientHello, in which case also adding the renegotiation - * info extension is NOT RECOMMENDED as per RFC 5746 Section 3.4. */ - if( ssl->renego_status != MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) - return; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding renegotiation extension" ) ); - - if( end < p || (size_t)( end - p ) < 5 + ssl->verify_data_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); - return; - } - - /* - * Secure renegotiation - */ - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO ) & 0xFF ); - - *p++ = 0x00; - *p++ = ( ssl->verify_data_len + 1 ) & 0xFF; - *p++ = ssl->verify_data_len & 0xFF; - - memcpy( p, ssl->own_verify_data, ssl->verify_data_len ); - - *olen = 5 + ssl->verify_data_len; -} -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - -/* - * Only if we handle at least one key exchange that needs signatures. - */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) -static void ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen ) -{ - unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; - size_t sig_alg_len = 0; - const int *md; -#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C) - unsigned char *sig_alg_list = buf + 6; -#endif - - *olen = 0; - - if( ssl->conf->max_minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 ) - return; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding signature_algorithms extension" ) ); - - for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ ) - { -#if defined(MBEDTLS_ECDSA_C) - sig_alg_len += 2; -#endif -#if defined(MBEDTLS_RSA_C) - sig_alg_len += 2; -#endif - } - - if( end < p || (size_t)( end - p ) < sig_alg_len + 6 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); - return; - } - - /* - * Prepare signature_algorithms extension (TLS 1.2) - */ - sig_alg_len = 0; - - for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ ) - { -#if defined(MBEDTLS_ECDSA_C) - sig_alg_list[sig_alg_len++] = mbedtls_ssl_hash_from_md_alg( *md ); - sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_ECDSA; -#endif -#if defined(MBEDTLS_RSA_C) - sig_alg_list[sig_alg_len++] = mbedtls_ssl_hash_from_md_alg( *md ); - sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_RSA; -#endif - } - - /* - * enum { - * none(0), md5(1), sha1(2), sha224(3), sha256(4), sha384(5), - * sha512(6), (255) - * } HashAlgorithm; - * - * enum { anonymous(0), rsa(1), dsa(2), ecdsa(3), (255) } - * SignatureAlgorithm; - * - * struct { - * HashAlgorithm hash; - * SignatureAlgorithm signature; - * } SignatureAndHashAlgorithm; - * - * SignatureAndHashAlgorithm - * supported_signature_algorithms<2..2^16-2>; - */ - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SIG_ALG >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SIG_ALG ) & 0xFF ); - - *p++ = (unsigned char)( ( ( sig_alg_len + 2 ) >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( ( sig_alg_len + 2 ) ) & 0xFF ); - - *p++ = (unsigned char)( ( sig_alg_len >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( sig_alg_len ) & 0xFF ); - - *olen = 6 + sig_alg_len; -} -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && - MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ - -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -static void ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen ) -{ - unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; - unsigned char *elliptic_curve_list = p + 6; - size_t elliptic_curve_len = 0; - const mbedtls_ecp_curve_info *info; -#if defined(MBEDTLS_ECP_C) - const mbedtls_ecp_group_id *grp_id; -#else - ((void) ssl); -#endif - - *olen = 0; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_elliptic_curves extension" ) ); - -#if defined(MBEDTLS_ECP_C) - for( grp_id = ssl->conf->curve_list; *grp_id != MBEDTLS_ECP_DP_NONE; grp_id++ ) -#else - for( info = mbedtls_ecp_curve_list(); info->grp_id != MBEDTLS_ECP_DP_NONE; info++ ) -#endif - { -#if defined(MBEDTLS_ECP_C) - info = mbedtls_ecp_curve_info_from_grp_id( *grp_id ); -#endif - if( info == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid curve in ssl configuration" ) ); - return; - } - - elliptic_curve_len += 2; - } - - if( end < p || (size_t)( end - p ) < 6 + elliptic_curve_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); - return; - } - - elliptic_curve_len = 0; - -#if defined(MBEDTLS_ECP_C) - for( grp_id = ssl->conf->curve_list; *grp_id != MBEDTLS_ECP_DP_NONE; grp_id++ ) -#else - for( info = mbedtls_ecp_curve_list(); info->grp_id != MBEDTLS_ECP_DP_NONE; info++ ) -#endif - { -#if defined(MBEDTLS_ECP_C) - info = mbedtls_ecp_curve_info_from_grp_id( *grp_id ); -#endif - elliptic_curve_list[elliptic_curve_len++] = info->tls_id >> 8; - elliptic_curve_list[elliptic_curve_len++] = info->tls_id & 0xFF; - } - - if( elliptic_curve_len == 0 ) - return; - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES ) & 0xFF ); - - *p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) ) & 0xFF ); - - *p++ = (unsigned char)( ( ( elliptic_curve_len ) >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( ( elliptic_curve_len ) ) & 0xFF ); - - *olen = 6 + elliptic_curve_len; -} - -static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen ) -{ - unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; - - *olen = 0; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_point_formats extension" ) ); - - if( end < p || (size_t)( end - p ) < 6 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); - return; - } - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS ) & 0xFF ); - - *p++ = 0x00; - *p++ = 2; - - *p++ = 1; - *p++ = MBEDTLS_ECP_PF_UNCOMPRESSED; - - *olen = 6; -} -#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || - MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen ) -{ - int ret; - unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; - size_t kkpp_len; - - *olen = 0; - - /* Skip costly extension if we can't use EC J-PAKE anyway */ - if( mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 ) - return; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding ecjpake_kkpp extension" ) ); - - if( end - p < 4 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); - return; - } - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP ) & 0xFF ); - - /* - * We may need to send ClientHello multiple times for Hello verification. - * We don't want to compute fresh values every time (both for performance - * and consistency reasons), so cache the extension content. - */ - if( ssl->handshake->ecjpake_cache == NULL || - ssl->handshake->ecjpake_cache_len == 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "generating new ecjpake parameters" ) ); - - ret = mbedtls_ecjpake_write_round_one( &ssl->handshake->ecjpake_ctx, - p + 2, end - p - 2, &kkpp_len, - ssl->conf->f_rng, ssl->conf->p_rng ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1 , "mbedtls_ecjpake_write_round_one", ret ); - return; - } - - ssl->handshake->ecjpake_cache = mbedtls_calloc( 1, kkpp_len ); - if( ssl->handshake->ecjpake_cache == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "allocation failed" ) ); - return; - } - - memcpy( ssl->handshake->ecjpake_cache, p + 2, kkpp_len ); - ssl->handshake->ecjpake_cache_len = kkpp_len; - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "re-using cached ecjpake parameters" ) ); - - kkpp_len = ssl->handshake->ecjpake_cache_len; - - if( (size_t)( end - p - 2 ) < kkpp_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); - return; - } - - memcpy( p + 2, ssl->handshake->ecjpake_cache, kkpp_len ); - } - - *p++ = (unsigned char)( ( kkpp_len >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( kkpp_len ) & 0xFF ); - - *olen = kkpp_len + 4; -} -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) -static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen ) -{ - unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; - - *olen = 0; - - if( ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE ) { - return; - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding max_fragment_length extension" ) ); - - if( end < p || (size_t)( end - p ) < 5 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); - return; - } - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH ) & 0xFF ); - - *p++ = 0x00; - *p++ = 1; - - *p++ = ssl->conf->mfl_code; - - *olen = 5; -} -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) -static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, size_t *olen ) -{ - unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; - - *olen = 0; - - if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED ) - { - return; - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding truncated_hmac extension" ) ); - - if( end < p || (size_t)( end - p ) < 4 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); - return; - } - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC ) & 0xFF ); - - *p++ = 0x00; - *p++ = 0x00; - - *olen = 4; -} -#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) -static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, size_t *olen ) -{ - unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; - - *olen = 0; - - if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED || - ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) - { - return; - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding encrypt_then_mac " - "extension" ) ); - - if( end < p || (size_t)( end - p ) < 4 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); - return; - } - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC ) & 0xFF ); - - *p++ = 0x00; - *p++ = 0x00; - - *olen = 4; -} -#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) -static void ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, size_t *olen ) -{ - unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; - - *olen = 0; - - if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED || - ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) - { - return; - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding extended_master_secret " - "extension" ) ); - - if( end < p || (size_t)( end - p ) < 4 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); - return; - } - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET ) & 0xFF ); - - *p++ = 0x00; - *p++ = 0x00; - - *olen = 4; -} -#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) -static void ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, size_t *olen ) -{ - unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; - size_t tlen = ssl->session_negotiate->ticket_len; - - *olen = 0; - - if( ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED ) - { - return; - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding session ticket extension" ) ); - - if( end < p || (size_t)( end - p ) < 4 + tlen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); - return; - } - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET ) & 0xFF ); - - *p++ = (unsigned char)( ( tlen >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( tlen ) & 0xFF ); - - *olen = 4; - - if( ssl->session_negotiate->ticket == NULL || tlen == 0 ) - { - return; - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "sending session ticket of length %d", tlen ) ); - - memcpy( p, ssl->session_negotiate->ticket, tlen ); - - *olen += tlen; -} -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -#if defined(MBEDTLS_SSL_ALPN) -static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, size_t *olen ) -{ - unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; - size_t alpnlen = 0; - const char **cur; - - *olen = 0; - - if( ssl->conf->alpn_list == NULL ) - { - return; - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding alpn extension" ) ); - - for( cur = ssl->conf->alpn_list; *cur != NULL; cur++ ) - alpnlen += (unsigned char)( strlen( *cur ) & 0xFF ) + 1; - - if( end < p || (size_t)( end - p ) < 6 + alpnlen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); - return; - } - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN ) & 0xFF ); - - /* - * opaque ProtocolName<1..2^8-1>; - * - * struct { - * ProtocolName protocol_name_list<2..2^16-1> - * } ProtocolNameList; - */ - - /* Skip writing extension and list length for now */ - p += 4; - - for( cur = ssl->conf->alpn_list; *cur != NULL; cur++ ) - { - *p = (unsigned char)( strlen( *cur ) & 0xFF ); - memcpy( p + 1, *cur, *p ); - p += 1 + *p; - } - - *olen = p - buf; - - /* List length = olen - 2 (ext_type) - 2 (ext_len) - 2 (list_len) */ - buf[4] = (unsigned char)( ( ( *olen - 6 ) >> 8 ) & 0xFF ); - buf[5] = (unsigned char)( ( ( *olen - 6 ) ) & 0xFF ); - - /* Extension length = olen - 2 (ext_type) - 2 (ext_len) */ - buf[2] = (unsigned char)( ( ( *olen - 4 ) >> 8 ) & 0xFF ); - buf[3] = (unsigned char)( ( ( *olen - 4 ) ) & 0xFF ); -} -#endif /* MBEDTLS_SSL_ALPN */ - -/* - * Generate random bytes for ClientHello - */ -static int ssl_generate_random( mbedtls_ssl_context *ssl ) -{ - int ret; - unsigned char *p = ssl->handshake->randbytes; -#if defined(MBEDTLS_HAVE_TIME) - mbedtls_time_t t; -#endif - - /* - * When responding to a verify request, MUST reuse random (RFC 6347 4.2.1) - */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl->handshake->verify_cookie != NULL ) - { - return( 0 ); - } -#endif - -#if defined(MBEDTLS_HAVE_TIME) - t = mbedtls_time( NULL ); - *p++ = (unsigned char)( t >> 24 ); - *p++ = (unsigned char)( t >> 16 ); - *p++ = (unsigned char)( t >> 8 ); - *p++ = (unsigned char)( t ); - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, current time: %lu", t ) ); -#else - if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 4 ) ) != 0 ) - return( ret ); - - p += 4; -#endif /* MBEDTLS_HAVE_TIME */ - - if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 28 ) ) != 0 ) - return( ret ); - - return( 0 ); -} - -/** - * \brief Validate cipher suite against config in SSL context. - * - * \param suite_info cipher suite to validate - * \param ssl SSL context - * \param min_minor_ver Minimal minor version to accept a cipher suite - * \param max_minor_ver Maximal minor version to accept a cipher suite - * - * \return 0 if valid, else 1 - */ -static int ssl_validate_ciphersuite( const mbedtls_ssl_ciphersuite_t * suite_info, - const mbedtls_ssl_context * ssl, - int min_minor_ver, int max_minor_ver ) -{ - (void) ssl; - if( suite_info == NULL ) - return( 1 ); - - if( suite_info->min_minor_ver > max_minor_ver || - suite_info->max_minor_ver < min_minor_ver ) - return( 1 ); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ( suite_info->flags & MBEDTLS_CIPHERSUITE_NODTLS ) ) - return( 1 ); -#endif - -#if defined(MBEDTLS_ARC4_C) - if( ssl->conf->arc4_disabled == MBEDTLS_SSL_ARC4_DISABLED && - suite_info->cipher == MBEDTLS_CIPHER_ARC4_128 ) - return( 1 ); -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - if( suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE && - mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 ) - return( 1 ); -#endif - - /* Don't suggest PSK-based ciphersuite if no PSK is available. */ -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) - if( mbedtls_ssl_ciphersuite_uses_psk( suite_info ) && - ssl_conf_has_static_psk( ssl->conf ) == 0 ) - { - return( 1 ); - } -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ - - return( 0 ); -} - -static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) -{ - int ret; - size_t i, n, olen, ext_len = 0; - unsigned char *buf; - unsigned char *p, *q; - unsigned char offer_compress; - const int *ciphersuites; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info; -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - int uses_ec = 0; -#endif - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client hello" ) ); - - if( ssl->conf->f_rng == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "no RNG provided") ); - return( MBEDTLS_ERR_SSL_NO_RNG ); - } - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE ) -#endif - { - ssl->major_ver = ssl->conf->min_major_ver; - ssl->minor_ver = ssl->conf->min_minor_ver; - } - - if( ssl->conf->max_major_ver == 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "configured max major version is invalid, " - "consider using mbedtls_ssl_config_defaults()" ) ); - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - /* - * 0 . 0 handshake type - * 1 . 3 handshake length - * 4 . 5 highest version supported - * 6 . 9 current UNIX time - * 10 . 37 random bytes - */ - buf = ssl->out_msg; - p = buf + 4; - - mbedtls_ssl_write_version( ssl->conf->max_major_ver, ssl->conf->max_minor_ver, - ssl->conf->transport, p ); - p += 2; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, max version: [%d:%d]", - buf[4], buf[5] ) ); - - if( ( ret = ssl_generate_random( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_generate_random", ret ); - return( ret ); - } - - memcpy( p, ssl->handshake->randbytes, 32 ); - MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, random bytes", p, 32 ); - p += 32; - - /* - * 38 . 38 session id length - * 39 . 39+n session id - * 39+n . 39+n DTLS only: cookie length (1 byte) - * 40+n . .. DTSL only: cookie - * .. . .. ciphersuitelist length (2 bytes) - * .. . .. ciphersuitelist - * .. . .. compression methods length (1 byte) - * .. . .. compression methods - * .. . .. extensions length (2 bytes) - * .. . .. extensions - */ - n = ssl->session_negotiate->id_len; - - if( n < 16 || n > 32 || -#if defined(MBEDTLS_SSL_RENEGOTIATION) - ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE || -#endif - ssl->handshake->resume == 0 ) - { - n = 0; - } - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - /* - * RFC 5077 section 3.4: "When presenting a ticket, the client MAY - * generate and include a Session ID in the TLS ClientHello." - */ -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE ) -#endif - { - if( ssl->session_negotiate->ticket != NULL && - ssl->session_negotiate->ticket_len != 0 ) - { - ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->session_negotiate->id, 32 ); - - if( ret != 0 ) - return( ret ); - - ssl->session_negotiate->id_len = n = 32; - } - } -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - - *p++ = (unsigned char) n; - - for( i = 0; i < n; i++ ) - *p++ = ssl->session_negotiate->id[i]; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, session id len.: %d", n ) ); - MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, session id", buf + 39, n ); - - /* - * DTLS cookie - */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - if( ssl->handshake->verify_cookie == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "no verify cookie to send" ) ); - *p++ = 0; - } - else - { - MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, cookie", - ssl->handshake->verify_cookie, - ssl->handshake->verify_cookie_len ); - - *p++ = ssl->handshake->verify_cookie_len; - memcpy( p, ssl->handshake->verify_cookie, - ssl->handshake->verify_cookie_len ); - p += ssl->handshake->verify_cookie_len; - } - } -#endif - - /* - * Ciphersuite list - */ - ciphersuites = ssl->conf->ciphersuite_list[ssl->minor_ver]; - - /* Skip writing ciphersuite length for now */ - n = 0; - q = p; - p += 2; - - for( i = 0; ciphersuites[i] != 0; i++ ) - { - ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( ciphersuites[i] ); - - if( ssl_validate_ciphersuite( ciphersuite_info, ssl, - ssl->conf->min_minor_ver, - ssl->conf->max_minor_ver ) != 0 ) - continue; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %04x", - ciphersuites[i] ) ); - -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - uses_ec |= mbedtls_ssl_ciphersuite_uses_ec( ciphersuite_info ); -#endif - - n++; - *p++ = (unsigned char)( ciphersuites[i] >> 8 ); - *p++ = (unsigned char)( ciphersuites[i] ); - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, got %d ciphersuites (excluding SCSVs)", n ) ); - - /* - * Add TLS_EMPTY_RENEGOTIATION_INFO_SCSV - */ -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE ) -#endif - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding EMPTY_RENEGOTIATION_INFO_SCSV" ) ); - *p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO >> 8 ); - *p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO ); - n++; - } - - /* Some versions of OpenSSL don't handle it correctly if not at end */ -#if defined(MBEDTLS_SSL_FALLBACK_SCSV) - if( ssl->conf->fallback == MBEDTLS_SSL_IS_FALLBACK ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding FALLBACK_SCSV" ) ); - *p++ = (unsigned char)( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 ); - *p++ = (unsigned char)( MBEDTLS_SSL_FALLBACK_SCSV_VALUE ); - n++; - } -#endif - - *q++ = (unsigned char)( n >> 7 ); - *q++ = (unsigned char)( n << 1 ); - -#if defined(MBEDTLS_ZLIB_SUPPORT) - offer_compress = 1; -#else - offer_compress = 0; -#endif - - /* - * We don't support compression with DTLS right now: if many records come - * in the same datagram, uncompressing one could overwrite the next one. - * We don't want to add complexity for handling that case unless there is - * an actual need for it. - */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - offer_compress = 0; -#endif - - if( offer_compress ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress len.: %d", 2 ) ); - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress alg.: %d %d", - MBEDTLS_SSL_COMPRESS_DEFLATE, MBEDTLS_SSL_COMPRESS_NULL ) ); - - *p++ = 2; - *p++ = MBEDTLS_SSL_COMPRESS_DEFLATE; - *p++ = MBEDTLS_SSL_COMPRESS_NULL; - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress len.: %d", 1 ) ); - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress alg.: %d", - MBEDTLS_SSL_COMPRESS_NULL ) ); - - *p++ = 1; - *p++ = MBEDTLS_SSL_COMPRESS_NULL; - } - - // First write extensions, then the total length - // -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - ssl_write_hostname_ext( ssl, p + 2 + ext_len, &olen ); - ext_len += olen; -#endif - - /* Note that TLS_EMPTY_RENEGOTIATION_INFO_SCSV is always added - * even if MBEDTLS_SSL_RENEGOTIATION is not defined. */ -#if defined(MBEDTLS_SSL_RENEGOTIATION) - ssl_write_renegotiation_ext( ssl, p + 2 + ext_len, &olen ); - ext_len += olen; -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) - ssl_write_signature_algorithms_ext( ssl, p + 2 + ext_len, &olen ); - ext_len += olen; -#endif - -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - if( uses_ec ) - { - ssl_write_supported_elliptic_curves_ext( ssl, p + 2 + ext_len, &olen ); - ext_len += olen; - - ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len, &olen ); - ext_len += olen; - } -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - ssl_write_ecjpake_kkpp_ext( ssl, p + 2 + ext_len, &olen ); - ext_len += olen; -#endif - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - ssl_write_max_fragment_length_ext( ssl, p + 2 + ext_len, &olen ); - ext_len += olen; -#endif - -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) - ssl_write_truncated_hmac_ext( ssl, p + 2 + ext_len, &olen ); - ext_len += olen; -#endif - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - ssl_write_encrypt_then_mac_ext( ssl, p + 2 + ext_len, &olen ); - ext_len += olen; -#endif - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - ssl_write_extended_ms_ext( ssl, p + 2 + ext_len, &olen ); - ext_len += olen; -#endif - -#if defined(MBEDTLS_SSL_ALPN) - ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen ); - ext_len += olen; -#endif - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - ssl_write_session_ticket_ext( ssl, p + 2 + ext_len, &olen ); - ext_len += olen; -#endif - - /* olen unused if all extensions are disabled */ - ((void) olen); - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, total extension length: %d", - ext_len ) ); - - if( ext_len > 0 ) - { - *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( ext_len ) & 0xFF ); - p += ext_len; - } - - ssl->out_msglen = p - buf; - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = MBEDTLS_SSL_HS_CLIENT_HELLO; - - ssl->state++; - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - mbedtls_ssl_send_flight_completed( ssl ); -#endif - - if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); - return( ret ); - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret ); - return( ret ); - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write client hello" ) ); - - return( 0 ); -} - -static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ) - { - /* Check verify-data in constant-time. The length OTOH is no secret */ - if( len != 1 + ssl->verify_data_len * 2 || - buf[0] != ssl->verify_data_len * 2 || - mbedtls_ssl_safer_memcmp( buf + 1, - ssl->own_verify_data, ssl->verify_data_len ) != 0 || - mbedtls_ssl_safer_memcmp( buf + 1 + ssl->verify_data_len, - ssl->peer_verify_data, ssl->verify_data_len ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - } - else -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - { - if( len != 1 || buf[0] != 0x00 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-zero length renegotiation info" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION; - } - - return( 0 ); -} - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) -static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ - /* - * server should use the extension only if we did, - * and if so the server's value should match ours (and len is always 1) - */ - if( ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE || - len != 1 || - buf[0] != ssl->conf->mfl_code ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching max fragment length extension" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - return( 0 ); -} -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) -static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ - if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED || - len != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching truncated HMAC extension" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - ((void) buf); - - ssl->session_negotiate->trunc_hmac = MBEDTLS_SSL_TRUNC_HMAC_ENABLED; - - return( 0 ); -} -#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) -static int ssl_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ - if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED || - ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 || - len != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching encrypt-then-MAC extension" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - ((void) buf); - - ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED; - - return( 0 ); -} -#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) -static int ssl_parse_extended_ms_ext( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ - if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED || - ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 || - len != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching extended master secret extension" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - ((void) buf); - - ssl->handshake->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED; - - return( 0 ); -} -#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) -static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ - if( ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED || - len != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching session ticket extension" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - ((void) buf); - - ssl->handshake->new_session_ticket = 1; - - return( 0 ); -} -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ - size_t list_size; - const unsigned char *p; - - if( len == 0 || (size_t)( buf[0] + 1 ) != len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - list_size = buf[0]; - - p = buf + 1; - while( list_size > 0 ) - { - if( p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED || - p[0] == MBEDTLS_ECP_PF_COMPRESSED ) - { -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) - ssl->handshake->ecdh_ctx.point_format = p[0]; -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - ssl->handshake->ecjpake_ctx.point_format = p[0]; -#endif - MBEDTLS_SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) ); - return( 0 ); - } - - list_size--; - p++; - } - - MBEDTLS_SSL_DEBUG_MSG( 1, ( "no point format in common" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); -} -#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || - MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ - int ret; - - if( ssl->transform_negotiate->ciphersuite_info->key_exchange != - MBEDTLS_KEY_EXCHANGE_ECJPAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip ecjpake kkpp extension" ) ); - return( 0 ); - } - - /* If we got here, we no longer need our cached extension */ - mbedtls_free( ssl->handshake->ecjpake_cache ); - ssl->handshake->ecjpake_cache = NULL; - ssl->handshake->ecjpake_cache_len = 0; - - if( ( ret = mbedtls_ecjpake_read_round_one( &ssl->handshake->ecjpake_ctx, - buf, len ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_one", ret ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( ret ); - } - - return( 0 ); -} -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_SSL_ALPN) -static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl, - const unsigned char *buf, size_t len ) -{ - size_t list_len, name_len; - const char **p; - - /* If we didn't send it, the server shouldn't send it */ - if( ssl->conf->alpn_list == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching ALPN extension" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - /* - * opaque ProtocolName<1..2^8-1>; - * - * struct { - * ProtocolName protocol_name_list<2..2^16-1> - * } ProtocolNameList; - * - * the "ProtocolNameList" MUST contain exactly one "ProtocolName" - */ - - /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */ - if( len < 4 ) - { - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - list_len = ( buf[0] << 8 ) | buf[1]; - if( list_len != len - 2 ) - { - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - name_len = buf[2]; - if( name_len != list_len - 1 ) - { - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - /* Check that the server chosen protocol was in our list and save it */ - for( p = ssl->conf->alpn_list; *p != NULL; p++ ) - { - if( name_len == strlen( *p ) && - memcmp( buf + 3, *p, name_len ) == 0 ) - { - ssl->alpn_chosen = *p; - return( 0 ); - } - } - - MBEDTLS_SSL_DEBUG_MSG( 1, ( "ALPN extension: no matching protocol" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); -} -#endif /* MBEDTLS_SSL_ALPN */ - -/* - * Parse HelloVerifyRequest. Only called after verifying the HS type. - */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) -static int ssl_parse_hello_verify_request( mbedtls_ssl_context *ssl ) -{ - const unsigned char *p = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ); - int major_ver, minor_ver; - unsigned char cookie_len; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse hello verify request" ) ); - - /* - * struct { - * ProtocolVersion server_version; - * opaque cookie<0..2^8-1>; - * } HelloVerifyRequest; - */ - MBEDTLS_SSL_DEBUG_BUF( 3, "server version", p, 2 ); - mbedtls_ssl_read_version( &major_ver, &minor_ver, ssl->conf->transport, p ); - p += 2; - - /* - * Since the RFC is not clear on this point, accept DTLS 1.0 (TLS 1.1) - * even is lower than our min version. - */ - if( major_ver < MBEDTLS_SSL_MAJOR_VERSION_3 || - minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 || - major_ver > ssl->conf->max_major_ver || - minor_ver > ssl->conf->max_minor_ver ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server version" ) ); - - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION ); - - return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION ); - } - - cookie_len = *p++; - MBEDTLS_SSL_DEBUG_BUF( 3, "cookie", p, cookie_len ); - - if( ( ssl->in_msg + ssl->in_msglen ) - p < cookie_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, - ( "cookie length does not match incoming message size" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - mbedtls_free( ssl->handshake->verify_cookie ); - - ssl->handshake->verify_cookie = mbedtls_calloc( 1, cookie_len ); - if( ssl->handshake->verify_cookie == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc failed (%d bytes)", cookie_len ) ); - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - } - - memcpy( ssl->handshake->verify_cookie, p, cookie_len ); - ssl->handshake->verify_cookie_len = cookie_len; - - /* Start over at ClientHello */ - ssl->state = MBEDTLS_SSL_CLIENT_HELLO; - mbedtls_ssl_reset_checksum( ssl ); - - mbedtls_ssl_recv_flight_completed( ssl ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse hello verify request" ) ); - - return( 0 ); -} -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) -{ - int ret, i; - size_t n; - size_t ext_len; - unsigned char *buf, *ext; - unsigned char comp; -#if defined(MBEDTLS_ZLIB_SUPPORT) - int accept_comp; -#endif -#if defined(MBEDTLS_SSL_RENEGOTIATION) - int renegotiation_info_seen = 0; -#endif - int handshake_failure = 0; - const mbedtls_ssl_ciphersuite_t *suite_info; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server hello" ) ); - - buf = ssl->in_msg; - - if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) - { - /* No alert on a read error. */ - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); - return( ret ); - } - - if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) - { -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) - { - ssl->renego_records_seen++; - - if( ssl->conf->renego_max_records >= 0 && - ssl->renego_records_seen > ssl->conf->renego_max_records ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation requested, " - "but not honored by server" ) ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } - - MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-handshake message during renego" ) ); - - ssl->keep_current_message = 1; - return( MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO ); - } -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - if( buf[0] == MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "received hello verify request" ) ); - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello" ) ); - return( ssl_parse_hello_verify_request( ssl ) ); - } - else - { - /* We made it through the verification process */ - mbedtls_free( ssl->handshake->verify_cookie ); - ssl->handshake->verify_cookie = NULL; - ssl->handshake->verify_cookie_len = 0; - } - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - if( ssl->in_hslen < 38 + mbedtls_ssl_hs_hdr_len( ssl ) || - buf[0] != MBEDTLS_SSL_HS_SERVER_HELLO ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - /* - * 0 . 1 server_version - * 2 . 33 random (maybe including 4 bytes of Unix time) - * 34 . 34 session_id length = n - * 35 . 34+n session_id - * 35+n . 36+n cipher_suite - * 37+n . 37+n compression_method - * - * 38+n . 39+n extensions length (optional) - * 40+n . .. extensions - */ - buf += mbedtls_ssl_hs_hdr_len( ssl ); - - MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, version", buf + 0, 2 ); - mbedtls_ssl_read_version( &ssl->major_ver, &ssl->minor_ver, - ssl->conf->transport, buf + 0 ); - - if( ssl->major_ver < ssl->conf->min_major_ver || - ssl->minor_ver < ssl->conf->min_minor_ver || - ssl->major_ver > ssl->conf->max_major_ver || - ssl->minor_ver > ssl->conf->max_minor_ver ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "server version out of bounds - " - " min: [%d:%d], server: [%d:%d], max: [%d:%d]", - ssl->conf->min_major_ver, ssl->conf->min_minor_ver, - ssl->major_ver, ssl->minor_ver, - ssl->conf->max_major_ver, ssl->conf->max_minor_ver ) ); - - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION ); - - return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION ); - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", - ( (uint32_t) buf[2] << 24 ) | - ( (uint32_t) buf[3] << 16 ) | - ( (uint32_t) buf[4] << 8 ) | - ( (uint32_t) buf[5] ) ) ); - - memcpy( ssl->handshake->randbytes + 32, buf + 2, 32 ); - - n = buf[34]; - - MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, random bytes", buf + 2, 32 ); - - if( n > 32 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - if( ssl->in_hslen > mbedtls_ssl_hs_hdr_len( ssl ) + 39 + n ) - { - ext_len = ( ( buf[38 + n] << 8 ) - | ( buf[39 + n] ) ); - - if( ( ext_len > 0 && ext_len < 4 ) || - ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 40 + n + ext_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - } - else if( ssl->in_hslen == mbedtls_ssl_hs_hdr_len( ssl ) + 38 + n ) - { - ext_len = 0; - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - /* ciphersuite (used later) */ - i = ( buf[35 + n] << 8 ) | buf[36 + n]; - - /* - * Read and check compression - */ - comp = buf[37 + n]; - -#if defined(MBEDTLS_ZLIB_SUPPORT) - /* See comments in ssl_write_client_hello() */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - accept_comp = 0; - else -#endif - accept_comp = 1; - - if( comp != MBEDTLS_SSL_COMPRESS_NULL && - ( comp != MBEDTLS_SSL_COMPRESS_DEFLATE || accept_comp == 0 ) ) -#else /* MBEDTLS_ZLIB_SUPPORT */ - if( comp != MBEDTLS_SSL_COMPRESS_NULL ) -#endif/* MBEDTLS_ZLIB_SUPPORT */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "server hello, bad compression: %d", comp ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); - return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); - } - - /* - * Initialize update checksum functions - */ - ssl->transform_negotiate->ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( i ); - - if( ssl->transform_negotiate->ciphersuite_info == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "ciphersuite info for %04x not found", i ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - mbedtls_ssl_optimize_checksum( ssl, ssl->transform_negotiate->ciphersuite_info ); - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) ); - MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, session id", buf + 35, n ); - - /* - * Check if the session can be resumed - */ - if( ssl->handshake->resume == 0 || n == 0 || -#if defined(MBEDTLS_SSL_RENEGOTIATION) - ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE || -#endif - ssl->session_negotiate->ciphersuite != i || - ssl->session_negotiate->compression != comp || - ssl->session_negotiate->id_len != n || - memcmp( ssl->session_negotiate->id, buf + 35, n ) != 0 ) - { - ssl->state++; - ssl->handshake->resume = 0; -#if defined(MBEDTLS_HAVE_TIME) - ssl->session_negotiate->start = mbedtls_time( NULL ); -#endif - ssl->session_negotiate->ciphersuite = i; - ssl->session_negotiate->compression = comp; - ssl->session_negotiate->id_len = n; - memcpy( ssl->session_negotiate->id, buf + 35, n ); - } - else - { - ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC; - - if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); - return( ret ); - } - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "%s session has been resumed", - ssl->handshake->resume ? "a" : "no" ) ); - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %04x", i ) ); - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d", buf[37 + n] ) ); - - /* - * Perform cipher suite validation in same way as in ssl_write_client_hello. - */ - i = 0; - while( 1 ) - { - if( ssl->conf->ciphersuite_list[ssl->minor_ver][i] == 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - if( ssl->conf->ciphersuite_list[ssl->minor_ver][i++] == - ssl->session_negotiate->ciphersuite ) - { - break; - } - } - - suite_info = mbedtls_ssl_ciphersuite_from_id( ssl->session_negotiate->ciphersuite ); - if( ssl_validate_ciphersuite( suite_info, ssl, ssl->minor_ver, ssl->minor_ver ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %s", suite_info->name ) ); - -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA && - ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) - { - ssl->handshake->ecrs_enabled = 1; - } -#endif - - if( comp != MBEDTLS_SSL_COMPRESS_NULL -#if defined(MBEDTLS_ZLIB_SUPPORT) - && comp != MBEDTLS_SSL_COMPRESS_DEFLATE -#endif - ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - ssl->session_negotiate->compression = comp; - - ext = buf + 40 + n; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "server hello, total extension length: %d", ext_len ) ); - - while( ext_len ) - { - unsigned int ext_id = ( ( ext[0] << 8 ) - | ( ext[1] ) ); - unsigned int ext_size = ( ( ext[2] << 8 ) - | ( ext[3] ) ); - - if( ext_size + 4 > ext_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - switch( ext_id ) - { - case MBEDTLS_TLS_EXT_RENEGOTIATION_INFO: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) ); -#if defined(MBEDTLS_SSL_RENEGOTIATION) - renegotiation_info_seen = 1; -#endif - - if( ( ret = ssl_parse_renegotiation_info( ssl, ext + 4, - ext_size ) ) != 0 ) - return( ret ); - - break; - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found max_fragment_length extension" ) ); - - if( ( ret = ssl_parse_max_fragment_length_ext( ssl, - ext + 4, ext_size ) ) != 0 ) - { - return( ret ); - } - - break; -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) - case MBEDTLS_TLS_EXT_TRUNCATED_HMAC: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found truncated_hmac extension" ) ); - - if( ( ret = ssl_parse_truncated_hmac_ext( ssl, - ext + 4, ext_size ) ) != 0 ) - { - return( ret ); - } - - break; -#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found encrypt_then_mac extension" ) ); - - if( ( ret = ssl_parse_encrypt_then_mac_ext( ssl, - ext + 4, ext_size ) ) != 0 ) - { - return( ret ); - } - - break; -#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found extended_master_secret extension" ) ); - - if( ( ret = ssl_parse_extended_ms_ext( ssl, - ext + 4, ext_size ) ) != 0 ) - { - return( ret ); - } - - break; -#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - case MBEDTLS_TLS_EXT_SESSION_TICKET: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found session_ticket extension" ) ); - - if( ( ret = ssl_parse_session_ticket_ext( ssl, - ext + 4, ext_size ) ) != 0 ) - { - return( ret ); - } - - break; -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported_point_formats extension" ) ); - - if( ( ret = ssl_parse_supported_point_formats_ext( ssl, - ext + 4, ext_size ) ) != 0 ) - { - return( ret ); - } - - break; -#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || - MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - case MBEDTLS_TLS_EXT_ECJPAKE_KKPP: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ecjpake_kkpp extension" ) ); - - if( ( ret = ssl_parse_ecjpake_kkpp( ssl, - ext + 4, ext_size ) ) != 0 ) - { - return( ret ); - } - - break; -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_SSL_ALPN) - case MBEDTLS_TLS_EXT_ALPN: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found alpn extension" ) ); - - if( ( ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size ) ) != 0 ) - return( ret ); - - break; -#endif /* MBEDTLS_SSL_ALPN */ - - default: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)", - ext_id ) ); - } - - ext_len -= 4 + ext_size; - ext += 4 + ext_size; - - if( ext_len > 0 && ext_len < 4 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - } - - /* - * Renegotiation security checks - */ - if( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && - ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) ); - handshake_failure = 1; - } -#if defined(MBEDTLS_SSL_RENEGOTIATION) - else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && - ssl->secure_renegotiation == MBEDTLS_SSL_SECURE_RENEGOTIATION && - renegotiation_info_seen == 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension missing (secure)" ) ); - handshake_failure = 1; - } - else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && - ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && - ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation not allowed" ) ); - handshake_failure = 1; - } - else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && - ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && - renegotiation_info_seen == 1 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension present (legacy)" ) ); - handshake_failure = 1; - } -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - - if( handshake_failure == 1 ) - { - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello" ) ); - - return( 0 ); -} - -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) -static int ssl_parse_server_dh_params( mbedtls_ssl_context *ssl, unsigned char **p, - unsigned char *end ) -{ - int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - - /* - * Ephemeral DH parameters: - * - * struct { - * opaque dh_p<1..2^16-1>; - * opaque dh_g<1..2^16-1>; - * opaque dh_Ys<1..2^16-1>; - * } ServerDHParams; - */ - if( ( ret = mbedtls_dhm_read_params( &ssl->handshake->dhm_ctx, p, end ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 2, ( "mbedtls_dhm_read_params" ), ret ); - return( ret ); - } - - if( ssl->handshake->dhm_ctx.len * 8 < ssl->conf->dhm_min_bitlen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "DHM prime too short: %d < %d", - ssl->handshake->dhm_ctx.len * 8, - ssl->conf->dhm_min_bitlen ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - } - - MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P ); - MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->handshake->dhm_ctx.G ); - MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->handshake->dhm_ctx.GY ); - - return( ret ); -} -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) -static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl ) -{ - const mbedtls_ecp_curve_info *curve_info; - mbedtls_ecp_group_id grp_id; -#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) - grp_id = ssl->handshake->ecdh_ctx.grp.id; -#else - grp_id = ssl->handshake->ecdh_ctx.grp_id; -#endif - - curve_info = mbedtls_ecp_curve_info_from_grp_id( grp_id ); - if( curve_info == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDH curve: %s", curve_info->name ) ); - -#if defined(MBEDTLS_ECP_C) - if( mbedtls_ssl_check_curve( ssl, grp_id ) != 0 ) -#else - if( ssl->handshake->ecdh_ctx.grp.nbits < 163 || - ssl->handshake->ecdh_ctx.grp.nbits > 521 ) -#endif - return( -1 ); - - MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, - MBEDTLS_DEBUG_ECDH_QP ); - - return( 0 ); -} -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ - -#if defined(MBEDTLS_USE_PSA_CRYPTO) && \ - ( defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ) -static int ssl_parse_server_ecdh_params_psa( mbedtls_ssl_context *ssl, - unsigned char **p, - unsigned char *end ) -{ - uint16_t tls_id; - uint8_t ecpoint_len; - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - - /* - * Parse ECC group - */ - - if( end - *p < 4 ) - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - - /* First byte is curve_type; only named_curve is handled */ - if( *(*p)++ != MBEDTLS_ECP_TLS_NAMED_CURVE ) - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - - /* Next two bytes are the namedcurve value */ - tls_id = *(*p)++; - tls_id <<= 8; - tls_id |= *(*p)++; - - /* Convert EC group to PSA key type. */ - if( ( handshake->ecdh_psa_curve = - mbedtls_psa_parse_tls_ecc_group( tls_id ) ) == 0 ) - { - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - } - - /* - * Put peer's ECDH public key in the format understood by PSA. - */ - - ecpoint_len = *(*p)++; - if( (size_t)( end - *p ) < ecpoint_len ) - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - - if( mbedtls_psa_tls_ecpoint_to_psa_ec( handshake->ecdh_psa_curve, - *p, ecpoint_len, - handshake->ecdh_psa_peerkey, - sizeof( handshake->ecdh_psa_peerkey ), - &handshake->ecdh_psa_peerkey_len ) != 0 ) - { - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - } - - *p += ecpoint_len; - return( 0 ); -} -#endif /* MBEDTLS_USE_PSA_CRYPTO && - ( MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ) */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) -static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl, - unsigned char **p, - unsigned char *end ) -{ - int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - - /* - * Ephemeral ECDH parameters: - * - * struct { - * ECParameters curve_params; - * ECPoint public; - * } ServerECDHParams; - */ - if( ( ret = mbedtls_ecdh_read_params( &ssl->handshake->ecdh_ctx, - (const unsigned char **) p, end ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_read_params" ), ret ); -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) - ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; -#endif - return( ret ); - } - - if( ssl_check_server_ecdh_params( ssl ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message (ECDHE curve)" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - } - - return( ret ); -} -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) -static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl, - unsigned char **p, - unsigned char *end ) -{ - int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - size_t len; - ((void) ssl); - - /* - * PSK parameters: - * - * opaque psk_identity_hint<0..2^16-1>; - */ - if( end - (*p) < 2 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message " - "(psk_identity_hint length)" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - } - len = (*p)[0] << 8 | (*p)[1]; - *p += 2; - - if( end - (*p) < (int) len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message " - "(psk_identity_hint length)" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - } - - /* - * Note: we currently ignore the PKS identity hint, as we only allow one - * PSK to be provisionned on the client. This could be changed later if - * someone needs that feature. - */ - *p += len; - ret = 0; - - return( ret ); -} -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) -/* - * Generate a pre-master secret and encrypt it with the server's RSA key - */ -static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl, - size_t offset, size_t *olen, - size_t pms_offset ) -{ - int ret; - size_t len_bytes = ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ? 0 : 2; - unsigned char *p = ssl->handshake->premaster + pms_offset; - mbedtls_pk_context * peer_pk; - - if( offset + len_bytes > MBEDTLS_SSL_OUT_CONTENT_LEN ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small for encrypted pms" ) ); - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); - } - - /* - * Generate (part of) the pre-master as - * struct { - * ProtocolVersion client_version; - * opaque random[46]; - * } PreMasterSecret; - */ - mbedtls_ssl_write_version( ssl->conf->max_major_ver, ssl->conf->max_minor_ver, - ssl->conf->transport, p ); - - if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p + 2, 46 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "f_rng", ret ); - return( ret ); - } - - ssl->handshake->pmslen = 48; - -#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - peer_pk = &ssl->handshake->peer_pubkey; -#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - if( ssl->session_negotiate->peer_cert == NULL ) - { - /* Should never happen */ - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - peer_pk = &ssl->session_negotiate->peer_cert->pk; -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - - /* - * Now write it out, encrypted - */ - if( ! mbedtls_pk_can_do( peer_pk, MBEDTLS_PK_RSA ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "certificate key type mismatch" ) ); - return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH ); - } - - if( ( ret = mbedtls_pk_encrypt( peer_pk, - p, ssl->handshake->pmslen, - ssl->out_msg + offset + len_bytes, olen, - MBEDTLS_SSL_OUT_CONTENT_LEN - offset - len_bytes, - ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_rsa_pkcs1_encrypt", ret ); - return( ret ); - } - -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( len_bytes == 2 ) - { - ssl->out_msg[offset+0] = (unsigned char)( *olen >> 8 ); - ssl->out_msg[offset+1] = (unsigned char)( *olen ); - *olen += 2; - } -#endif - -#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - /* We don't need the peer's public key anymore. Free it. */ - mbedtls_pk_free( peer_pk ); -#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - return( 0 ); -} -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) -static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl, - unsigned char **p, - unsigned char *end, - mbedtls_md_type_t *md_alg, - mbedtls_pk_type_t *pk_alg ) -{ - ((void) ssl); - *md_alg = MBEDTLS_MD_NONE; - *pk_alg = MBEDTLS_PK_NONE; - - /* Only in TLS 1.2 */ - if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 ) - { - return( 0 ); - } - - if( (*p) + 2 > end ) - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - - /* - * Get hash algorithm - */ - if( ( *md_alg = mbedtls_ssl_md_alg_from_hash( (*p)[0] ) ) == MBEDTLS_MD_NONE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "Server used unsupported " - "HashAlgorithm %d", *(p)[0] ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - } - - /* - * Get signature algorithm - */ - if( ( *pk_alg = mbedtls_ssl_pk_alg_from_sig( (*p)[1] ) ) == MBEDTLS_PK_NONE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "server used unsupported " - "SignatureAlgorithm %d", (*p)[1] ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - } - - /* - * Check if the hash is acceptable - */ - if( mbedtls_ssl_check_sig_hash( ssl, *md_alg ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "server used HashAlgorithm %d that was not offered", - *(p)[0] ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used SignatureAlgorithm %d", (*p)[1] ) ); - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used HashAlgorithm %d", (*p)[0] ) ); - *p += 2; - - return( 0 ); -} -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) -static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl ) -{ - int ret; - const mbedtls_ecp_keypair *peer_key; - mbedtls_pk_context * peer_pk; - -#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - peer_pk = &ssl->handshake->peer_pubkey; -#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - if( ssl->session_negotiate->peer_cert == NULL ) - { - /* Should never happen */ - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - peer_pk = &ssl->session_negotiate->peer_cert->pk; -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - - if( ! mbedtls_pk_can_do( peer_pk, MBEDTLS_PK_ECKEY ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) ); - return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH ); - } - - peer_key = mbedtls_pk_ec( *peer_pk ); - - if( ( ret = mbedtls_ecdh_get_params( &ssl->handshake->ecdh_ctx, peer_key, - MBEDTLS_ECDH_THEIRS ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_get_params" ), ret ); - return( ret ); - } - - if( ssl_check_server_ecdh_params( ssl ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server certificate (ECDH curve)" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); - } - -#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - /* We don't need the peer's public key anymore. Free it, - * so that more RAM is available for upcoming expensive - * operations like ECDHE. */ - mbedtls_pk_free( peer_pk ); -#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - - return( ret ); -} -#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || - MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ - -static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) -{ - int ret; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->transform_negotiate->ciphersuite_info; - unsigned char *p = NULL, *end = NULL; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) ); - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) ); - ssl->state++; - return( 0 ); - } - ((void) p); - ((void) end); -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA ) - { - if( ( ret = ssl_get_ecdh_params_from_cert( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_get_ecdh_params_from_cert", ret ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( ret ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) ); - ssl->state++; - return( 0 ); - } - ((void) p); - ((void) end); -#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ - -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ssl->handshake->ecrs_enabled && - ssl->handshake->ecrs_state == ssl_ecrs_ske_start_processing ) - { - goto start_processing; - } -#endif - - if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); - return( ret ); - } - - if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } - - /* - * ServerKeyExchange may be skipped with PSK and RSA-PSK when the server - * doesn't use a psk_identity_hint - */ - if( ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE ) - { - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) - { - /* Current message is probably either - * CertificateRequest or ServerHelloDone */ - ssl->keep_current_message = 1; - goto exit; - } - - MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key exchange message must " - "not be skipped" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); - - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } - -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ssl->handshake->ecrs_enabled ) - ssl->handshake->ecrs_state = ssl_ecrs_ske_start_processing; - -start_processing: -#endif - p = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ); - end = ssl->in_msg + ssl->in_hslen; - MBEDTLS_SSL_DEBUG_BUF( 3, "server key exchange", p, end - p ); - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) - { - if( ssl_parse_server_psk_hint( ssl, &p, end ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - } - } /* FALLTROUGH */ -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) - ; /* nothing more to do */ - else -#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED || - MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ) - { - if( ssl_parse_server_dh_params( ssl, &p, end ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - } - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ -#if defined(MBEDTLS_USE_PSA_CRYPTO) && \ - ( defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ) - { - if( ssl_parse_server_ecdh_params_psa( ssl, &p, end ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - } - } - else -#endif /* MBEDTLS_USE_PSA_CRYPTO && - ( MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ) */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ) - { - if( ssl_parse_server_ecdh_params( ssl, &p, end ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - } - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) - { - ret = mbedtls_ecjpake_read_round_two( &ssl->handshake->ecjpake_ctx, - p, end - p ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_two", ret ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - } - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) - if( mbedtls_ssl_ciphersuite_uses_server_signature( ciphersuite_info ) ) - { - size_t sig_len, hashlen; - unsigned char hash[64]; - mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE; - mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE; - unsigned char *params = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ); - size_t params_len = p - params; - void *rs_ctx = NULL; - - mbedtls_pk_context * peer_pk; - - /* - * Handle the digitally-signed structure - */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) - { - if( ssl_parse_signature_algorithm( ssl, &p, end, - &md_alg, &pk_alg ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - } - - if( pk_alg != mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - } - } - else -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) - if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 ) - { - pk_alg = mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ); - - /* Default hash for ECDSA is SHA-1 */ - if( pk_alg == MBEDTLS_PK_ECDSA && md_alg == MBEDTLS_MD_NONE ) - md_alg = MBEDTLS_MD_SHA1; - } - else -#endif - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - /* - * Read signature - */ - - if( p > end - 2 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - } - sig_len = ( p[0] << 8 ) | p[1]; - p += 2; - - if( p != end - sig_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - } - - MBEDTLS_SSL_DEBUG_BUF( 3, "signature", p, sig_len ); - - /* - * Compute the hash that has been signed - */ -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) - if( md_alg == MBEDTLS_MD_NONE ) - { - hashlen = 36; - ret = mbedtls_ssl_get_key_exchange_md_ssl_tls( ssl, hash, params, - params_len ); - if( ret != 0 ) - return( ret ); - } - else -#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \ - MBEDTLS_SSL_PROTO_TLS1_1 */ -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( md_alg != MBEDTLS_MD_NONE ) - { - ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash, &hashlen, - params, params_len, - md_alg ); - if( ret != 0 ) - return( ret ); - } - else -#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ - MBEDTLS_SSL_PROTO_TLS1_2 */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen ); - -#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - peer_pk = &ssl->handshake->peer_pubkey; -#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - if( ssl->session_negotiate->peer_cert == NULL ) - { - /* Should never happen */ - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - peer_pk = &ssl->session_negotiate->peer_cert->pk; -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - - /* - * Verify signature - */ - if( !mbedtls_pk_can_do( peer_pk, pk_alg ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH ); - } - -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ssl->handshake->ecrs_enabled ) - rs_ctx = &ssl->handshake->ecrs_ctx.pk; -#endif - - if( ( ret = mbedtls_pk_verify_restartable( peer_pk, - md_alg, hash, hashlen, p, sig_len, rs_ctx ) ) != 0 ) - { -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS ) -#endif - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR ); - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret ); -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) - ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; -#endif - return( ret ); - } - -#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - /* We don't need the peer's public key anymore. Free it, - * so that more RAM is available for upcoming expensive - * operations like ECDHE. */ - mbedtls_pk_free( peer_pk ); -#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - } -#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ - -exit: - ssl->state++; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server key exchange" ) ); - - return( 0 ); -} - -#if ! defined(MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED) -static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl ) -{ - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->transform_negotiate->ciphersuite_info; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) ); - - if( ! mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) ); - ssl->state++; - return( 0 ); - } - - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); -} -#else /* MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */ -static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl ) -{ - int ret; - unsigned char *buf; - size_t n = 0; - size_t cert_type_len = 0, dn_len = 0; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->transform_negotiate->ciphersuite_info; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) ); - - if( ! mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) ); - ssl->state++; - return( 0 ); - } - - if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); - return( ret ); - } - - if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } - - ssl->state++; - ssl->client_auth = ( ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE_REQUEST ); - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "got %s certificate request", - ssl->client_auth ? "a" : "no" ) ); - - if( ssl->client_auth == 0 ) - { - /* Current message is probably the ServerHelloDone */ - ssl->keep_current_message = 1; - goto exit; - } - - /* - * struct { - * ClientCertificateType certificate_types<1..2^8-1>; - * SignatureAndHashAlgorithm - * supported_signature_algorithms<2^16-1>; -- TLS 1.2 only - * DistinguishedName certificate_authorities<0..2^16-1>; - * } CertificateRequest; - * - * Since we only support a single certificate on clients, let's just - * ignore all the information that's supposed to help us pick a - * certificate. - * - * We could check that our certificate matches the request, and bail out - * if it doesn't, but it's simpler to just send the certificate anyway, - * and give the server the opportunity to decide if it should terminate - * the connection when it doesn't like our certificate. - * - * Same goes for the hash in TLS 1.2's signature_algorithms: at this - * point we only have one hash available (see comments in - * write_certificate_verify), so let's just use what we have. - * - * However, we still minimally parse the message to check it is at least - * superficially sane. - */ - buf = ssl->in_msg; - - /* certificate_types */ - if( ssl->in_hslen <= mbedtls_ssl_hs_hdr_len( ssl ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST ); - } - cert_type_len = buf[mbedtls_ssl_hs_hdr_len( ssl )]; - n = cert_type_len; - - /* - * In the subsequent code there are two paths that read from buf: - * * the length of the signature algorithms field (if minor version of - * SSL is 3), - * * distinguished name length otherwise. - * Both reach at most the index: - * ...hdr_len + 2 + n, - * therefore the buffer length at this point must be greater than that - * regardless of the actual code path. - */ - if( ssl->in_hslen <= mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST ); - } - - /* supported_signature_algorithms */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) - { - size_t sig_alg_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] << 8 ) - | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n] ) ); -#if defined(MBEDTLS_DEBUG_C) - unsigned char* sig_alg; - size_t i; -#endif - - /* - * The furthest access in buf is in the loop few lines below: - * sig_alg[i + 1], - * where: - * sig_alg = buf + ...hdr_len + 3 + n, - * max(i) = sig_alg_len - 1. - * Therefore the furthest access is: - * buf[...hdr_len + 3 + n + sig_alg_len - 1 + 1], - * which reduces to: - * buf[...hdr_len + 3 + n + sig_alg_len], - * which is one less than we need the buf to be. - */ - if( ssl->in_hslen <= mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n + sig_alg_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST ); - } - -#if defined(MBEDTLS_DEBUG_C) - sig_alg = buf + mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n; - for( i = 0; i < sig_alg_len; i += 2 ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "Supported Signature Algorithm found: %d" - ",%d", sig_alg[i], sig_alg[i + 1] ) ); - } -#endif - - n += 2 + sig_alg_len; - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - - /* certificate_authorities */ - dn_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] << 8 ) - | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n] ) ); - - n += dn_len; - if( ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST ); - } - -exit: - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate request" ) ); - - return( 0 ); -} -#endif /* MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */ - -static int ssl_parse_server_hello_done( mbedtls_ssl_context *ssl ) -{ - int ret; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server hello done" ) ); - - if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); - return( ret ); - } - - if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } - - if( ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) || - ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_HELLO_DONE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE ); - } - - ssl->state++; - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - mbedtls_ssl_recv_flight_completed( ssl ); -#endif - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello done" ) ); - - return( 0 ); -} - -static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl ) -{ - int ret; - - size_t header_len; - size_t content_len; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->transform_negotiate->ciphersuite_info; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client key exchange" ) ); - -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA ) - { - /* - * DHM key exchange -- send G^X mod P - */ - content_len = ssl->handshake->dhm_ctx.len; - - ssl->out_msg[4] = (unsigned char)( content_len >> 8 ); - ssl->out_msg[5] = (unsigned char)( content_len ); - header_len = 6; - - ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx, - (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ), - &ssl->out_msg[header_len], content_len, - ssl->conf->f_rng, ssl->conf->p_rng ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_public", ret ); - return( ret ); - } - - MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->handshake->dhm_ctx.X ); - MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->handshake->dhm_ctx.GX ); - - if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx, - ssl->handshake->premaster, - MBEDTLS_PREMASTER_SIZE, - &ssl->handshake->pmslen, - ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret ); - return( ret ); - } - - MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K ); - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ -#if defined(MBEDTLS_USE_PSA_CRYPTO) && \ - ( defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ) - { - psa_status_t status; - psa_key_policy_t policy; - - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - - unsigned char own_pubkey[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH]; - size_t own_pubkey_len; - unsigned char *own_pubkey_ecpoint; - size_t own_pubkey_ecpoint_len; - - psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT; - - header_len = 4; - - MBEDTLS_SSL_DEBUG_MSG( 1, ( "Perform PSA-based ECDH computation." ) ); - - /* - * Generate EC private key for ECDHE exchange. - */ - - /* Allocate a new key slot for the private key. */ - - status = psa_allocate_key( &handshake->ecdh_psa_privkey ); - if( status != PSA_SUCCESS ) - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - - /* The master secret is obtained from the shared ECDH secret by - * applying the TLS 1.2 PRF with a specific salt and label. While - * the PSA Crypto API encourages combining key agreement schemes - * such as ECDH with fixed KDFs such as TLS 1.2 PRF, it does not - * yet support the provisioning of salt + label to the KDF. - * For the time being, we therefore need to split the computation - * of the ECDH secret and the application of the TLS 1.2 PRF. */ - policy = psa_key_policy_init(); - psa_key_policy_set_usage( &policy, - PSA_KEY_USAGE_DERIVE, - PSA_ALG_ECDH( PSA_ALG_SELECT_RAW ) ); - status = psa_set_key_policy( handshake->ecdh_psa_privkey, &policy ); - if( status != PSA_SUCCESS ) - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - - /* Generate ECDH private key. */ - status = psa_generate_key( handshake->ecdh_psa_privkey, - PSA_KEY_TYPE_ECC_KEYPAIR( handshake->ecdh_psa_curve ), - MBEDTLS_PSA_ECC_KEY_BITS_OF_CURVE( handshake->ecdh_psa_curve ), - NULL, 0 ); - if( status != PSA_SUCCESS ) - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - - /* Export the public part of the ECDH private key from PSA - * and convert it to ECPoint format used in ClientKeyExchange. */ - status = psa_export_public_key( handshake->ecdh_psa_privkey, - own_pubkey, sizeof( own_pubkey ), - &own_pubkey_len ); - if( status != PSA_SUCCESS ) - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - - if( mbedtls_psa_tls_psa_ec_to_ecpoint( own_pubkey, - own_pubkey_len, - &own_pubkey_ecpoint, - &own_pubkey_ecpoint_len ) != 0 ) - { - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - } - - /* Copy ECPoint structure to outgoing message buffer. */ - ssl->out_msg[header_len] = own_pubkey_ecpoint_len; - memcpy( ssl->out_msg + header_len + 1, - own_pubkey_ecpoint, own_pubkey_ecpoint_len ); - content_len = own_pubkey_ecpoint_len + 1; - - /* Compute ECDH shared secret. */ - status = psa_key_agreement( &generator, - handshake->ecdh_psa_privkey, - handshake->ecdh_psa_peerkey, - handshake->ecdh_psa_peerkey_len, - PSA_ALG_ECDH( PSA_ALG_SELECT_RAW ) ); - if( status != PSA_SUCCESS ) - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - - /* The ECDH secret is the premaster secret used for key derivation. */ - - ssl->handshake->pmslen = - MBEDTLS_PSA_ECC_KEY_BYTES_OF_CURVE( handshake->ecdh_psa_curve ); - - status = psa_generator_read( &generator, - ssl->handshake->premaster, - ssl->handshake->pmslen ); - if( status != PSA_SUCCESS ) - { - psa_generator_abort( &generator ); - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - } - - status = psa_generator_abort( &generator ); - if( status != PSA_SUCCESS ) - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - - status = psa_destroy_key( handshake->ecdh_psa_privkey ); - if( status != PSA_SUCCESS ) - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - handshake->ecdh_psa_privkey = 0; - } - else -#endif /* MBEDTLS_USE_PSA_CRYPTO && - ( MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ) */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA ) - { - /* - * ECDH key exchange -- send client public value - */ - header_len = 4; - -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ssl->handshake->ecrs_enabled ) - { - if( ssl->handshake->ecrs_state == ssl_ecrs_cke_ecdh_calc_secret ) - goto ecdh_calc_secret; - - mbedtls_ecdh_enable_restart( &ssl->handshake->ecdh_ctx ); - } -#endif - - ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx, - &content_len, - &ssl->out_msg[header_len], 1000, - ssl->conf->f_rng, ssl->conf->p_rng ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_public", ret ); -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) - ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; -#endif - return( ret ); - } - - MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, - MBEDTLS_DEBUG_ECDH_Q ); - -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ssl->handshake->ecrs_enabled ) - { - ssl->handshake->ecrs_n = content_len; - ssl->handshake->ecrs_state = ssl_ecrs_cke_ecdh_calc_secret; - } - -ecdh_calc_secret: - if( ssl->handshake->ecrs_enabled ) - content_len = ssl->handshake->ecrs_n; -#endif - if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx, - &ssl->handshake->pmslen, - ssl->handshake->premaster, - MBEDTLS_MPI_MAX_SIZE, - ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret ); -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) - ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; -#endif - return( ret ); - } - - MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, - MBEDTLS_DEBUG_ECDH_Z ); - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) - if( mbedtls_ssl_ciphersuite_uses_psk( ciphersuite_info ) ) - { - /* - * opaque psk_identity<0..2^16-1>; - */ - if( ssl_conf_has_static_psk( ssl->conf ) == 0 ) - { - /* We don't offer PSK suites if we don't have a PSK, - * and we check that the server's choice is among the - * ciphersuites we offered, so this should never happen. */ - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - header_len = 4; - content_len = ssl->conf->psk_identity_len; - - if( header_len + 2 + content_len > MBEDTLS_SSL_OUT_CONTENT_LEN ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "psk identity too long or " - "SSL buffer too short" ) ); - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); - } - - ssl->out_msg[header_len++] = (unsigned char)( content_len >> 8 ); - ssl->out_msg[header_len++] = (unsigned char)( content_len ); - - memcpy( ssl->out_msg + header_len, - ssl->conf->psk_identity, - ssl->conf->psk_identity_len ); - header_len += ssl->conf->psk_identity_len; - -#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ) - { - content_len = 0; - } - else -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) - { -#if defined(MBEDTLS_USE_PSA_CRYPTO) - /* Opaque PSKs are currently only supported for PSK-only suites. */ - if( ssl_conf_has_static_raw_psk( ssl->conf ) == 0 ) - return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - if( ( ret = ssl_write_encrypted_pms( ssl, header_len, - &content_len, 2 ) ) != 0 ) - return( ret ); - } - else -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ) - { -#if defined(MBEDTLS_USE_PSA_CRYPTO) - /* Opaque PSKs are currently only supported for PSK-only suites. */ - if( ssl_conf_has_static_raw_psk( ssl->conf ) == 0 ) - return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - /* - * ClientDiffieHellmanPublic public (DHM send G^X mod P) - */ - content_len = ssl->handshake->dhm_ctx.len; - - if( header_len + 2 + content_len > - MBEDTLS_SSL_OUT_CONTENT_LEN ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "psk identity or DHM size too long" - " or SSL buffer too short" ) ); - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); - } - - ssl->out_msg[header_len++] = (unsigned char)( content_len >> 8 ); - ssl->out_msg[header_len++] = (unsigned char)( content_len ); - - ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx, - (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ), - &ssl->out_msg[header_len], content_len, - ssl->conf->f_rng, ssl->conf->p_rng ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_public", ret ); - return( ret ); - } - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) - { -#if defined(MBEDTLS_USE_PSA_CRYPTO) - /* Opaque PSKs are currently only supported for PSK-only suites. */ - if( ssl_conf_has_static_raw_psk( ssl->conf ) == 0 ) - return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - /* - * ClientECDiffieHellmanPublic public; - */ - ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx, - &content_len, - &ssl->out_msg[header_len], - MBEDTLS_SSL_OUT_CONTENT_LEN - header_len, - ssl->conf->f_rng, ssl->conf->p_rng ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_public", ret ); - return( ret ); - } - - MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, - MBEDTLS_DEBUG_ECDH_Q ); - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - -#if defined(MBEDTLS_USE_PSA_CRYPTO) && \ - defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK && - ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 && - ssl_conf_has_static_raw_psk( ssl->conf ) == 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "skip PMS generation for opaque PSK" ) ); - } - else -#endif /* MBEDTLS_USE_PSA_CRYPTO && - MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */ - if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl, - ciphersuite_info->key_exchange ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret ); - return( ret ); - } - } - else -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA ) - { - header_len = 4; - if( ( ret = ssl_write_encrypted_pms( ssl, header_len, - &content_len, 0 ) ) != 0 ) - return( ret ); - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) - { - header_len = 4; - - ret = mbedtls_ecjpake_write_round_two( &ssl->handshake->ecjpake_ctx, - ssl->out_msg + header_len, - MBEDTLS_SSL_OUT_CONTENT_LEN - header_len, - &content_len, - ssl->conf->f_rng, ssl->conf->p_rng ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_write_round_two", ret ); - return( ret ); - } - - ret = mbedtls_ecjpake_derive_secret( &ssl->handshake->ecjpake_ctx, - ssl->handshake->premaster, 32, &ssl->handshake->pmslen, - ssl->conf->f_rng, ssl->conf->p_rng ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_derive_secret", ret ); - return( ret ); - } - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ - { - ((void) ciphersuite_info); - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - ssl->out_msglen = header_len + content_len; - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE; - - ssl->state++; - - if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); - return( ret ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write client key exchange" ) ); - - return( 0 ); -} - -#if !defined(MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED) -static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl ) -{ - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->transform_negotiate->ciphersuite_info; - int ret; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) ); - - if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret ); - return( ret ); - } - - if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) ); - ssl->state++; - return( 0 ); - } - - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); -} -#else /* !MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */ -static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl ) -{ - int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->transform_negotiate->ciphersuite_info; - size_t n = 0, offset = 0; - unsigned char hash[48]; - unsigned char *hash_start = hash; - mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE; - unsigned int hashlen; - void *rs_ctx = NULL; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) ); - -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ssl->handshake->ecrs_enabled && - ssl->handshake->ecrs_state == ssl_ecrs_crt_vrfy_sign ) - { - goto sign; - } -#endif - - if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret ); - return( ret ); - } - - if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) ); - ssl->state++; - return( 0 ); - } - - if( ssl->client_auth == 0 || mbedtls_ssl_own_cert( ssl ) == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) ); - ssl->state++; - return( 0 ); - } - - if( mbedtls_ssl_own_key( ssl ) == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key for certificate" ) ); - return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED ); - } - - /* - * Make a signature of the handshake digests - */ -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ssl->handshake->ecrs_enabled ) - ssl->handshake->ecrs_state = ssl_ecrs_crt_vrfy_sign; - -sign: -#endif - - ssl->handshake->calc_verify( ssl, hash ); - -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) - if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 ) - { - /* - * digitally-signed struct { - * opaque md5_hash[16]; - * opaque sha_hash[20]; - * }; - * - * md5_hash - * MD5(handshake_messages); - * - * sha_hash - * SHA(handshake_messages); - */ - hashlen = 36; - md_alg = MBEDTLS_MD_NONE; - - /* - * For ECDSA, default hash is SHA-1 only - */ - if( mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_ECDSA ) ) - { - hash_start += 16; - hashlen -= 16; - md_alg = MBEDTLS_MD_SHA1; - } - } - else -#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \ - MBEDTLS_SSL_PROTO_TLS1_1 */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) - { - /* - * digitally-signed struct { - * opaque handshake_messages[handshake_messages_length]; - * }; - * - * Taking shortcut here. We assume that the server always allows the - * PRF Hash function and has sent it in the allowed signature - * algorithms list received in the Certificate Request message. - * - * Until we encounter a server that does not, we will take this - * shortcut. - * - * Reason: Otherwise we should have running hashes for SHA512 and SHA224 - * in order to satisfy 'weird' needs from the server side. - */ - if( ssl->transform_negotiate->ciphersuite_info->mac == - MBEDTLS_MD_SHA384 ) - { - md_alg = MBEDTLS_MD_SHA384; - ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA384; - } - else - { - md_alg = MBEDTLS_MD_SHA256; - ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA256; - } - ssl->out_msg[5] = mbedtls_ssl_sig_from_pk( mbedtls_ssl_own_key( ssl ) ); - - /* Info from md_alg will be used instead */ - hashlen = 0; - offset = 2; - } - else -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ssl->handshake->ecrs_enabled ) - rs_ctx = &ssl->handshake->ecrs_ctx.pk; -#endif - - if( ( ret = mbedtls_pk_sign_restartable( mbedtls_ssl_own_key( ssl ), - md_alg, hash_start, hashlen, - ssl->out_msg + 6 + offset, &n, - ssl->conf->f_rng, ssl->conf->p_rng, rs_ctx ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret ); -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) - ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; -#endif - return( ret ); - } - - ssl->out_msg[4 + offset] = (unsigned char)( n >> 8 ); - ssl->out_msg[5 + offset] = (unsigned char)( n ); - - ssl->out_msglen = 6 + n + offset; - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE_VERIFY; - - ssl->state++; - - if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); - return( ret ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write certificate verify" ) ); - - return( ret ); -} -#endif /* MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) -static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl ) -{ - int ret; - uint32_t lifetime; - size_t ticket_len; - unsigned char *ticket; - const unsigned char *msg; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse new session ticket" ) ); - - if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); - return( ret ); - } - - if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } - - /* - * struct { - * uint32 ticket_lifetime_hint; - * opaque ticket<0..2^16-1>; - * } NewSessionTicket; - * - * 0 . 3 ticket_lifetime_hint - * 4 . 5 ticket_len (n) - * 6 . 5+n ticket content - */ - if( ssl->in_msg[0] != MBEDTLS_SSL_HS_NEW_SESSION_TICKET || - ssl->in_hslen < 6 + mbedtls_ssl_hs_hdr_len( ssl ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET ); - } - - msg = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ); - - lifetime = ( ((uint32_t) msg[0]) << 24 ) | ( msg[1] << 16 ) | - ( msg[2] << 8 ) | ( msg[3] ); - - ticket_len = ( msg[4] << 8 ) | ( msg[5] ); - - if( ticket_len + 6 + mbedtls_ssl_hs_hdr_len( ssl ) != ssl->in_hslen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET ); - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket length: %d", ticket_len ) ); - - /* We're not waiting for a NewSessionTicket message any more */ - ssl->handshake->new_session_ticket = 0; - ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC; - - /* - * Zero-length ticket means the server changed his mind and doesn't want - * to send a ticket after all, so just forget it - */ - if( ticket_len == 0 ) - return( 0 ); - - if( ssl->session != NULL && ssl->session->ticket != NULL ) - { - mbedtls_platform_zeroize( ssl->session->ticket, - ssl->session->ticket_len ); - mbedtls_free( ssl->session->ticket ); - ssl->session->ticket = NULL; - ssl->session->ticket_len = 0; - } - - mbedtls_platform_zeroize( ssl->session_negotiate->ticket, - ssl->session_negotiate->ticket_len ); - mbedtls_free( ssl->session_negotiate->ticket ); - ssl->session_negotiate->ticket = NULL; - ssl->session_negotiate->ticket_len = 0; - - if( ( ticket = mbedtls_calloc( 1, ticket_len ) ) == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "ticket alloc failed" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - } - - memcpy( ticket, msg + 6, ticket_len ); - - ssl->session_negotiate->ticket = ticket; - ssl->session_negotiate->ticket_len = ticket_len; - ssl->session_negotiate->ticket_lifetime = lifetime; - - /* - * RFC 5077 section 3.4: - * "If the client receives a session ticket from the server, then it - * discards any Session ID that was sent in the ServerHello." - */ - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket in use, discarding session id" ) ); - ssl->session_negotiate->id_len = 0; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse new session ticket" ) ); - - return( 0 ); -} -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -/* - * SSL handshake -- client side -- single step - */ -int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl ) -{ - int ret = 0; - - if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER || ssl->handshake == NULL ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "client state: %d", ssl->state ) ); - - if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) - return( ret ); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING ) - { - if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 ) - return( ret ); - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - /* Change state now, so that it is right in mbedtls_ssl_read_record(), used - * by DTLS for dropping out-of-sequence ChangeCipherSpec records */ -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - if( ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC && - ssl->handshake->new_session_ticket != 0 ) - { - ssl->state = MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET; - } -#endif - - switch( ssl->state ) - { - case MBEDTLS_SSL_HELLO_REQUEST: - ssl->state = MBEDTLS_SSL_CLIENT_HELLO; - break; - - /* - * ==> ClientHello - */ - case MBEDTLS_SSL_CLIENT_HELLO: - ret = ssl_write_client_hello( ssl ); - break; - - /* - * <== ServerHello - * Certificate - * ( ServerKeyExchange ) - * ( CertificateRequest ) - * ServerHelloDone - */ - case MBEDTLS_SSL_SERVER_HELLO: - ret = ssl_parse_server_hello( ssl ); - break; - - case MBEDTLS_SSL_SERVER_CERTIFICATE: - ret = mbedtls_ssl_parse_certificate( ssl ); - break; - - case MBEDTLS_SSL_SERVER_KEY_EXCHANGE: - ret = ssl_parse_server_key_exchange( ssl ); - break; - - case MBEDTLS_SSL_CERTIFICATE_REQUEST: - ret = ssl_parse_certificate_request( ssl ); - break; - - case MBEDTLS_SSL_SERVER_HELLO_DONE: - ret = ssl_parse_server_hello_done( ssl ); - break; - - /* - * ==> ( Certificate/Alert ) - * ClientKeyExchange - * ( CertificateVerify ) - * ChangeCipherSpec - * Finished - */ - case MBEDTLS_SSL_CLIENT_CERTIFICATE: - ret = mbedtls_ssl_write_certificate( ssl ); - break; - - case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE: - ret = ssl_write_client_key_exchange( ssl ); - break; - - case MBEDTLS_SSL_CERTIFICATE_VERIFY: - ret = ssl_write_certificate_verify( ssl ); - break; - - case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC: - ret = mbedtls_ssl_write_change_cipher_spec( ssl ); - break; - - case MBEDTLS_SSL_CLIENT_FINISHED: - ret = mbedtls_ssl_write_finished( ssl ); - break; - - /* - * <== ( NewSessionTicket ) - * ChangeCipherSpec - * Finished - */ -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - case MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET: - ret = ssl_parse_new_session_ticket( ssl ); - break; -#endif - - case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC: - ret = mbedtls_ssl_parse_change_cipher_spec( ssl ); - break; - - case MBEDTLS_SSL_SERVER_FINISHED: - ret = mbedtls_ssl_parse_finished( ssl ); - break; - - case MBEDTLS_SSL_FLUSH_BUFFERS: - MBEDTLS_SSL_DEBUG_MSG( 2, ( "handshake: done" ) ); - ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP; - break; - - case MBEDTLS_SSL_HANDSHAKE_WRAPUP: - mbedtls_ssl_handshake_wrapup( ssl ); - break; - - default: - MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) ); - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - return( ret ); -} -#endif /* MBEDTLS_SSL_CLI_C */ diff --git a/library/ssl_cookie.c b/library/ssl_cookie.c deleted file mode 100644 index 56e9bdd2b..000000000 --- a/library/ssl_cookie.c +++ /dev/null @@ -1,256 +0,0 @@ -/* - * DTLS cookie callbacks implementation - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -/* - * These session callbacks use a simple chained list - * to store and retrieve the session information. - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_SSL_COOKIE_C) - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#include "mbedtls/ssl_cookie.h" -#include "mbedtls/ssl_internal.h" -#include "mbedtls/platform_util.h" - -#include - -/* - * If DTLS is in use, then at least one of SHA-1, SHA-256, SHA-512 is - * available. Try SHA-256 first, 512 wastes resources since we need to stay - * with max 32 bytes of cookie for DTLS 1.0 - */ -#if defined(MBEDTLS_SHA256_C) -#define COOKIE_MD MBEDTLS_MD_SHA224 -#define COOKIE_MD_OUTLEN 32 -#define COOKIE_HMAC_LEN 28 -#elif defined(MBEDTLS_SHA512_C) -#define COOKIE_MD MBEDTLS_MD_SHA384 -#define COOKIE_MD_OUTLEN 48 -#define COOKIE_HMAC_LEN 28 -#elif defined(MBEDTLS_SHA1_C) -#define COOKIE_MD MBEDTLS_MD_SHA1 -#define COOKIE_MD_OUTLEN 20 -#define COOKIE_HMAC_LEN 20 -#else -#error "DTLS hello verify needs SHA-1 or SHA-2" -#endif - -/* - * Cookies are formed of a 4-bytes timestamp (or serial number) and - * an HMAC of timestemp and client ID. - */ -#define COOKIE_LEN ( 4 + COOKIE_HMAC_LEN ) - -void mbedtls_ssl_cookie_init( mbedtls_ssl_cookie_ctx *ctx ) -{ - mbedtls_md_init( &ctx->hmac_ctx ); -#if !defined(MBEDTLS_HAVE_TIME) - ctx->serial = 0; -#endif - ctx->timeout = MBEDTLS_SSL_COOKIE_TIMEOUT; - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_init( &ctx->mutex ); -#endif -} - -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 ) -{ - mbedtls_md_free( &ctx->hmac_ctx ); - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_free( &ctx->mutex ); -#endif - - mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ssl_cookie_ctx ) ); -} - -int mbedtls_ssl_cookie_setup( mbedtls_ssl_cookie_ctx *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - unsigned char key[COOKIE_MD_OUTLEN]; - - if( ( ret = f_rng( p_rng, key, sizeof( key ) ) ) != 0 ) - return( ret ); - - ret = mbedtls_md_setup( &ctx->hmac_ctx, mbedtls_md_info_from_type( COOKIE_MD ), 1 ); - if( ret != 0 ) - return( ret ); - - ret = mbedtls_md_hmac_starts( &ctx->hmac_ctx, key, sizeof( key ) ); - if( ret != 0 ) - return( ret ); - - mbedtls_platform_zeroize( key, sizeof( key ) ); - - return( 0 ); -} - -/* - * Generate the HMAC part of a cookie - */ -static int ssl_cookie_hmac( mbedtls_md_context_t *hmac_ctx, - const unsigned char time[4], - unsigned char **p, unsigned char *end, - const unsigned char *cli_id, size_t cli_id_len ) -{ - unsigned char hmac_out[COOKIE_MD_OUTLEN]; - - if( (size_t)( end - *p ) < COOKIE_HMAC_LEN ) - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); - - if( mbedtls_md_hmac_reset( hmac_ctx ) != 0 || - mbedtls_md_hmac_update( hmac_ctx, time, 4 ) != 0 || - mbedtls_md_hmac_update( hmac_ctx, cli_id, cli_id_len ) != 0 || - mbedtls_md_hmac_finish( hmac_ctx, hmac_out ) != 0 ) - { - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - memcpy( *p, hmac_out, COOKIE_HMAC_LEN ); - *p += COOKIE_HMAC_LEN; - - 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 ) -{ - int ret; - 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 ); - - if( (size_t)( end - *p ) < COOKIE_LEN ) - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); - -#if defined(MBEDTLS_HAVE_TIME) - t = (unsigned long) mbedtls_time( NULL ); -#else - t = ctx->serial++; -#endif - - (*p)[0] = (unsigned char)( t >> 24 ); - (*p)[1] = (unsigned char)( t >> 16 ); - (*p)[2] = (unsigned char)( t >> 8 ); - (*p)[3] = (unsigned char)( t ); - *p += 4; - -#if defined(MBEDTLS_THREADING_C) - if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR + ret ); -#endif - - ret = ssl_cookie_hmac( &ctx->hmac_ctx, *p - 4, - p, end, cli_id, cli_id_len ); - -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR + - MBEDTLS_ERR_THREADING_MUTEX_ERROR ); -#endif - - 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 ) -{ - unsigned char ref_hmac[COOKIE_HMAC_LEN]; - int ret = 0; - unsigned char *p = ref_hmac; - 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 ); - -#if defined(MBEDTLS_THREADING_C) - if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR + ret ); -#endif - - if( ssl_cookie_hmac( &ctx->hmac_ctx, cookie, - &p, p + sizeof( ref_hmac ), - cli_id, cli_id_len ) != 0 ) - ret = -1; - -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR + - MBEDTLS_ERR_THREADING_MUTEX_ERROR ); -#endif - - if( ret != 0 ) - return( ret ); - - if( mbedtls_ssl_safer_memcmp( cookie + 4, ref_hmac, sizeof( ref_hmac ) ) != 0 ) - return( -1 ); - -#if defined(MBEDTLS_HAVE_TIME) - cur_time = (unsigned long) mbedtls_time( NULL ); -#else - cur_time = ctx->serial; -#endif - - cookie_time = ( (unsigned long) cookie[0] << 24 ) | - ( (unsigned long) cookie[1] << 16 ) | - ( (unsigned long) cookie[2] << 8 ) | - ( (unsigned long) cookie[3] ); - - if( ctx->timeout != 0 && cur_time - cookie_time > ctx->timeout ) - return( -1 ); - - return( 0 ); -} -#endif /* MBEDTLS_SSL_COOKIE_C */ diff --git a/library/ssl_srv.c b/library/ssl_srv.c deleted file mode 100644 index b8e10d6dc..000000000 --- a/library/ssl_srv.c +++ /dev/null @@ -1,4437 +0,0 @@ -/* - * SSLv3/TLSv1 server-side functions - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_SSL_SRV_C) - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#include "mbedtls/debug.h" -#include "mbedtls/ssl.h" -#include "mbedtls/ssl_internal.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_ECP_C) -#include "mbedtls/ecp.h" -#endif - -#if defined(MBEDTLS_HAVE_TIME) -#include "mbedtls/platform_time.h" -#endif - -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) -int mbedtls_ssl_set_client_transport_id( mbedtls_ssl_context *ssl, - const unsigned char *info, - size_t ilen ) -{ - if( ssl->conf->endpoint != MBEDTLS_SSL_IS_SERVER ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - mbedtls_free( ssl->cli_id ); - - if( ( ssl->cli_id = mbedtls_calloc( 1, ilen ) ) == NULL ) - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - - memcpy( ssl->cli_id, info, ilen ); - ssl->cli_id_len = ilen; - - return( 0 ); -} - -void mbedtls_ssl_conf_dtls_cookies( mbedtls_ssl_config *conf, - mbedtls_ssl_cookie_write_t *f_cookie_write, - mbedtls_ssl_cookie_check_t *f_cookie_check, - void *p_cookie ) -{ - conf->f_cookie_write = f_cookie_write; - conf->f_cookie_check = f_cookie_check; - conf->p_cookie = p_cookie; -} -#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) -static int ssl_parse_servername_ext( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ - int ret; - size_t servername_list_size, hostname_len; - const unsigned char *p; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "parse ServerName extension" ) ); - - if( len < 2 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - servername_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) ); - if( servername_list_size + 2 != len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - p = buf + 2; - while( servername_list_size > 2 ) - { - hostname_len = ( ( p[1] << 8 ) | p[2] ); - if( hostname_len + 3 > servername_list_size ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - if( p[0] == MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME ) - { - ret = ssl->conf->f_sni( ssl->conf->p_sni, - ssl, p + 3, hostname_len ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_sni_wrapper", ret ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNRECOGNIZED_NAME ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - return( 0 ); - } - - servername_list_size -= hostname_len + 3; - p += hostname_len + 3; - } - - if( servername_list_size != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - return( 0 ); -} -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) -static int ssl_conf_has_psk_or_cb( mbedtls_ssl_config const *conf ) -{ - if( conf->f_psk != NULL ) - return( 1 ); - - if( conf->psk_identity_len == 0 || conf->psk_identity == NULL ) - return( 0 ); - - if( conf->psk != NULL && conf->psk_len != 0 ) - return( 1 ); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if( conf->psk_opaque != 0 ) - return( 1 ); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - return( 0 ); -} - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -static int ssl_use_opaque_psk( mbedtls_ssl_context const *ssl ) -{ - if( ssl->conf->f_psk != NULL ) - { - /* If we've used a callback to select the PSK, - * the static configuration is irrelevant. */ - - if( ssl->handshake->psk_opaque != 0 ) - return( 1 ); - - return( 0 ); - } - - if( ssl->conf->psk_opaque != 0 ) - return( 1 ); - - return( 0 ); -} -#endif /* MBEDTLS_USE_PSA_CRYPTO */ -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ - -static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ) - { - /* Check verify-data in constant-time. The length OTOH is no secret */ - if( len != 1 + ssl->verify_data_len || - buf[0] != ssl->verify_data_len || - mbedtls_ssl_safer_memcmp( buf + 1, ssl->peer_verify_data, - ssl->verify_data_len ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - } - else -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - { - if( len != 1 || buf[0] != 0x0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-zero length renegotiation info" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION; - } - - return( 0 ); -} - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) - -/* - * Status of the implementation of signature-algorithms extension: - * - * Currently, we are only considering the signature-algorithm extension - * to pick a ciphersuite which allows us to send the ServerKeyExchange - * message with a signature-hash combination that the user allows. - * - * We do *not* check whether all certificates in our certificate - * chain are signed with an allowed signature-hash pair. - * This needs to be done at a later stage. - * - */ -static int ssl_parse_signature_algorithms_ext( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ - size_t sig_alg_list_size; - - const unsigned char *p; - const unsigned char *end = buf + len; - - mbedtls_md_type_t md_cur; - mbedtls_pk_type_t sig_cur; - - if ( len < 2 ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - sig_alg_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) ); - if( sig_alg_list_size + 2 != len || - sig_alg_list_size % 2 != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - /* Currently we only guarantee signing the ServerKeyExchange message according - * to the constraints specified in this extension (see above), so it suffices - * to remember only one suitable hash for each possible signature algorithm. - * - * This will change when we also consider certificate signatures, - * in which case we will need to remember the whole signature-hash - * pair list from the extension. - */ - - for( p = buf + 2; p < end; p += 2 ) - { - /* Silently ignore unknown signature or hash algorithms. */ - - if( ( sig_cur = mbedtls_ssl_pk_alg_from_sig( p[1] ) ) == MBEDTLS_PK_NONE ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext" - " unknown sig alg encoding %d", p[1] ) ); - continue; - } - - /* Check if we support the hash the user proposes */ - md_cur = mbedtls_ssl_md_alg_from_hash( p[0] ); - if( md_cur == MBEDTLS_MD_NONE ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext:" - " unknown hash alg encoding %d", p[0] ) ); - continue; - } - - if( mbedtls_ssl_check_sig_hash( ssl, md_cur ) == 0 ) - { - mbedtls_ssl_sig_hash_set_add( &ssl->handshake->hash_algs, sig_cur, md_cur ); - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext:" - " match sig %d and hash %d", - sig_cur, md_cur ) ); - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext: " - "hash alg %d not supported", md_cur ) ); - } - } - - return( 0 ); -} -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && - MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ - -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -static int ssl_parse_supported_elliptic_curves( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ - size_t list_size, our_size; - const unsigned char *p; - const mbedtls_ecp_curve_info *curve_info, **curves; - - if ( len < 2 ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - list_size = ( ( buf[0] << 8 ) | ( buf[1] ) ); - if( list_size + 2 != len || - list_size % 2 != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - /* Should never happen unless client duplicates the extension */ - if( ssl->handshake->curves != NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - /* Don't allow our peer to make us allocate too much memory, - * and leave room for a final 0 */ - our_size = list_size / 2 + 1; - if( our_size > MBEDTLS_ECP_DP_MAX ) - our_size = MBEDTLS_ECP_DP_MAX; - - if( ( curves = mbedtls_calloc( our_size, sizeof( *curves ) ) ) == NULL ) - { - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - } - - ssl->handshake->curves = curves; - - p = buf + 2; - while( list_size > 0 && our_size > 1 ) - { - curve_info = mbedtls_ecp_curve_info_from_tls_id( ( p[0] << 8 ) | p[1] ); - - if( curve_info != NULL ) - { - *curves++ = curve_info; - our_size--; - } - - list_size -= 2; - p += 2; - } - - return( 0 ); -} - -static int ssl_parse_supported_point_formats( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ - size_t list_size; - const unsigned char *p; - - if( len == 0 || (size_t)( buf[0] + 1 ) != len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - list_size = buf[0]; - - p = buf + 1; - while( list_size > 0 ) - { - if( p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED || - p[0] == MBEDTLS_ECP_PF_COMPRESSED ) - { -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) - ssl->handshake->ecdh_ctx.point_format = p[0]; -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - ssl->handshake->ecjpake_ctx.point_format = p[0]; -#endif - MBEDTLS_SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) ); - return( 0 ); - } - - list_size--; - p++; - } - - return( 0 ); -} -#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || - MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ - int ret; - - if( mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip ecjpake kkpp extension" ) ); - return( 0 ); - } - - if( ( ret = mbedtls_ecjpake_read_round_one( &ssl->handshake->ecjpake_ctx, - buf, len ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_one", ret ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); - return( ret ); - } - - /* Only mark the extension as OK when we're sure it is */ - ssl->handshake->cli_exts |= MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK; - - return( 0 ); -} -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) -static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ - if( len != 1 || buf[0] >= MBEDTLS_SSL_MAX_FRAG_LEN_INVALID ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - ssl->session_negotiate->mfl_code = buf[0]; - - return( 0 ); -} -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) -static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ - if( len != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - ((void) buf); - - if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_ENABLED ) - ssl->session_negotiate->trunc_hmac = MBEDTLS_SSL_TRUNC_HMAC_ENABLED; - - return( 0 ); -} -#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) -static int ssl_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ - if( len != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - ((void) buf); - - if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED && - ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 ) - { - ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED; - } - - return( 0 ); -} -#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) -static int ssl_parse_extended_ms_ext( mbedtls_ssl_context *ssl, - const unsigned char *buf, - size_t len ) -{ - if( len != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - ((void) buf); - - if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED && - ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 ) - { - ssl->handshake->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED; - } - - return( 0 ); -} -#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) -static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t len ) -{ - int ret; - mbedtls_ssl_session session; - - mbedtls_ssl_session_init( &session ); - - if( ssl->conf->f_ticket_parse == NULL || - ssl->conf->f_ticket_write == NULL ) - { - return( 0 ); - } - - /* Remember the client asked us to send a new ticket */ - ssl->handshake->new_session_ticket = 1; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket length: %d", len ) ); - - if( len == 0 ) - return( 0 ); - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket rejected: renegotiating" ) ); - return( 0 ); - } -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - - /* - * Failures are ok: just ignore the ticket and proceed. - */ - if( ( ret = ssl->conf->f_ticket_parse( ssl->conf->p_ticket, &session, - buf, len ) ) != 0 ) - { - mbedtls_ssl_session_free( &session ); - - if( ret == MBEDTLS_ERR_SSL_INVALID_MAC ) - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket is not authentic" ) ); - else if( ret == MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED ) - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket is expired" ) ); - else - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_ticket_parse", ret ); - - return( 0 ); - } - - /* - * Keep the session ID sent by the client, since we MUST send it back to - * inform them we're accepting the ticket (RFC 5077 section 3.4) - */ - session.id_len = ssl->session_negotiate->id_len; - memcpy( &session.id, ssl->session_negotiate->id, session.id_len ); - - mbedtls_ssl_session_free( ssl->session_negotiate ); - memcpy( ssl->session_negotiate, &session, sizeof( mbedtls_ssl_session ) ); - - /* Zeroize instead of free as we copied the content */ - mbedtls_platform_zeroize( &session, sizeof( mbedtls_ssl_session ) ); - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "session successfully restored from ticket" ) ); - - ssl->handshake->resume = 1; - - /* Don't send a new ticket after all, this one is OK */ - ssl->handshake->new_session_ticket = 0; - - return( 0 ); -} -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -#if defined(MBEDTLS_SSL_ALPN) -static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl, - const unsigned char *buf, size_t len ) -{ - size_t list_len, cur_len, ours_len; - const unsigned char *theirs, *start, *end; - const char **ours; - - /* If ALPN not configured, just ignore the extension */ - if( ssl->conf->alpn_list == NULL ) - return( 0 ); - - /* - * opaque ProtocolName<1..2^8-1>; - * - * struct { - * ProtocolName protocol_name_list<2..2^16-1> - * } ProtocolNameList; - */ - - /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */ - if( len < 4 ) - { - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - list_len = ( buf[0] << 8 ) | buf[1]; - if( list_len != len - 2 ) - { - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - /* - * Validate peer's list (lengths) - */ - start = buf + 2; - end = buf + len; - for( theirs = start; theirs != end; theirs += cur_len ) - { - cur_len = *theirs++; - - /* Current identifier must fit in list */ - if( cur_len > (size_t)( end - theirs ) ) - { - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - /* Empty strings MUST NOT be included */ - if( cur_len == 0 ) - { - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - } - - /* - * Use our order of preference - */ - for( ours = ssl->conf->alpn_list; *ours != NULL; ours++ ) - { - ours_len = strlen( *ours ); - for( theirs = start; theirs != end; theirs += cur_len ) - { - cur_len = *theirs++; - - if( cur_len == ours_len && - memcmp( theirs, *ours, cur_len ) == 0 ) - { - ssl->alpn_chosen = *ours; - return( 0 ); - } - } - } - - /* If we get there, no match was found */ - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); -} -#endif /* MBEDTLS_SSL_ALPN */ - -/* - * Auxiliary functions for ServerHello parsing and related actions - */ - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -/* - * Return 0 if the given key uses one of the acceptable curves, -1 otherwise - */ -#if defined(MBEDTLS_ECDSA_C) -static int ssl_check_key_curve( mbedtls_pk_context *pk, - const mbedtls_ecp_curve_info **curves ) -{ - const mbedtls_ecp_curve_info **crv = curves; - mbedtls_ecp_group_id grp_id = mbedtls_pk_ec( *pk )->grp.id; - - while( *crv != NULL ) - { - if( (*crv)->grp_id == grp_id ) - return( 0 ); - crv++; - } - - return( -1 ); -} -#endif /* MBEDTLS_ECDSA_C */ - -/* - * Try picking a certificate for this ciphersuite, - * return 0 on success and -1 on failure. - */ -static int ssl_pick_cert( mbedtls_ssl_context *ssl, - const mbedtls_ssl_ciphersuite_t * ciphersuite_info ) -{ - mbedtls_ssl_key_cert *cur, *list, *fallback = NULL; - mbedtls_pk_type_t pk_alg = - mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ); - uint32_t flags; - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - if( ssl->handshake->sni_key_cert != NULL ) - list = ssl->handshake->sni_key_cert; - else -#endif - list = ssl->conf->key_cert; - - if( pk_alg == MBEDTLS_PK_NONE ) - return( 0 ); - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite requires certificate" ) ); - - if( list == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server has no certificate" ) ); - return( -1 ); - } - - for( cur = list; cur != NULL; cur = cur->next ) - { - MBEDTLS_SSL_DEBUG_CRT( 3, "candidate certificate chain, certificate", - cur->cert ); - - if( ! mbedtls_pk_can_do( &cur->cert->pk, pk_alg ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: key type" ) ); - continue; - } - - /* - * This avoids sending the client a cert it'll reject based on - * keyUsage or other extensions. - * - * It also allows the user to provision different certificates for - * different uses based on keyUsage, eg if they want to avoid signing - * and decrypting with the same RSA key. - */ - if( mbedtls_ssl_check_cert_usage( cur->cert, ciphersuite_info, - MBEDTLS_SSL_IS_SERVER, &flags ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: " - "(extended) key usage extension" ) ); - continue; - } - -#if defined(MBEDTLS_ECDSA_C) - if( pk_alg == MBEDTLS_PK_ECDSA && - ssl_check_key_curve( &cur->cert->pk, ssl->handshake->curves ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: elliptic curve" ) ); - continue; - } -#endif - - /* - * Try to select a SHA-1 certificate for pre-1.2 clients, but still - * present them a SHA-higher cert rather than failing if it's the only - * one we got that satisfies the other conditions. - */ - if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 && - cur->cert->sig_md != MBEDTLS_MD_SHA1 ) - { - if( fallback == NULL ) - fallback = cur; - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate not preferred: " - "sha-2 with pre-TLS 1.2 client" ) ); - continue; - } - } - - /* If we get there, we got a winner */ - break; - } - - if( cur == NULL ) - cur = fallback; - - /* Do not update ssl->handshake->key_cert unless there is a match */ - if( cur != NULL ) - { - ssl->handshake->key_cert = cur; - MBEDTLS_SSL_DEBUG_CRT( 3, "selected certificate chain, certificate", - ssl->handshake->key_cert->cert ); - return( 0 ); - } - - return( -1 ); -} -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -/* - * Check if a given ciphersuite is suitable for use with our config/keys/etc - * Sets ciphersuite_info only if the suite matches. - */ -static int ssl_ciphersuite_match( mbedtls_ssl_context *ssl, int suite_id, - const mbedtls_ssl_ciphersuite_t **ciphersuite_info ) -{ - const mbedtls_ssl_ciphersuite_t *suite_info; - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) - mbedtls_pk_type_t sig_type; -#endif - - suite_info = mbedtls_ssl_ciphersuite_from_id( suite_id ); - if( suite_info == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "trying ciphersuite: %s", suite_info->name ) ); - - if( suite_info->min_minor_ver > ssl->minor_ver || - suite_info->max_minor_ver < ssl->minor_ver ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: version" ) ); - return( 0 ); - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ( suite_info->flags & MBEDTLS_CIPHERSUITE_NODTLS ) ) - return( 0 ); -#endif - -#if defined(MBEDTLS_ARC4_C) - if( ssl->conf->arc4_disabled == MBEDTLS_SSL_ARC4_DISABLED && - suite_info->cipher == MBEDTLS_CIPHER_ARC4_128 ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: rc4" ) ); - return( 0 ); - } -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - if( suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE && - ( ssl->handshake->cli_exts & MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK ) == 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: ecjpake " - "not configured or ext missing" ) ); - return( 0 ); - } -#endif - - -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) - if( mbedtls_ssl_ciphersuite_uses_ec( suite_info ) && - ( ssl->handshake->curves == NULL || - ssl->handshake->curves[0] == NULL ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: " - "no common elliptic curve" ) ); - return( 0 ); - } -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) - /* If the ciphersuite requires a pre-shared key and we don't - * have one, skip it now rather than failing later */ - if( mbedtls_ssl_ciphersuite_uses_psk( suite_info ) && - ssl_conf_has_psk_or_cb( ssl->conf ) == 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: no pre-shared key" ) ); - return( 0 ); - } -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) - /* If the ciphersuite requires signing, check whether - * a suitable hash algorithm is present. */ - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) - { - sig_type = mbedtls_ssl_get_ciphersuite_sig_alg( suite_info ); - if( sig_type != MBEDTLS_PK_NONE && - mbedtls_ssl_sig_hash_set_find( &ssl->handshake->hash_algs, sig_type ) == MBEDTLS_MD_NONE ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: no suitable hash algorithm " - "for signature algorithm %d", sig_type ) ); - return( 0 ); - } - } - -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && - MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - /* - * Final check: if ciphersuite requires us to have a - * certificate/key of a particular type: - * - select the appropriate certificate if we have one, or - * - try the next ciphersuite if we don't - * This must be done last since we modify the key_cert list. - */ - if( ssl_pick_cert( ssl, suite_info ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: " - "no suitable certificate" ) ); - return( 0 ); - } -#endif - - *ciphersuite_info = suite_info; - return( 0 ); -} - -#if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO) -static int ssl_parse_client_hello_v2( mbedtls_ssl_context *ssl ) -{ - int ret, got_common_suite; - unsigned int i, j; - size_t n; - unsigned int ciph_len, sess_len, chal_len; - unsigned char *buf, *p; - const int *ciphersuites; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client hello v2" ) ); - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "client hello v2 illegal for renegotiation" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - - buf = ssl->in_hdr; - - MBEDTLS_SSL_DEBUG_BUF( 4, "record header", buf, 5 ); - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v2, message type: %d", - buf[2] ) ); - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v2, message len.: %d", - ( ( buf[0] & 0x7F ) << 8 ) | buf[1] ) ); - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v2, max. version: [%d:%d]", - buf[3], buf[4] ) ); - - /* - * SSLv2 Client Hello - * - * Record layer: - * 0 . 1 message length - * - * SSL layer: - * 2 . 2 message type - * 3 . 4 protocol version - */ - if( buf[2] != MBEDTLS_SSL_HS_CLIENT_HELLO || - buf[3] != MBEDTLS_SSL_MAJOR_VERSION_3 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - n = ( ( buf[0] << 8 ) | buf[1] ) & 0x7FFF; - - if( n < 17 || n > 512 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - ssl->major_ver = MBEDTLS_SSL_MAJOR_VERSION_3; - ssl->minor_ver = ( buf[4] <= ssl->conf->max_minor_ver ) - ? buf[4] : ssl->conf->max_minor_ver; - - if( ssl->minor_ver < ssl->conf->min_minor_ver ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "client only supports ssl smaller than minimum" - " [%d:%d] < [%d:%d]", - ssl->major_ver, ssl->minor_ver, - ssl->conf->min_major_ver, ssl->conf->min_minor_ver ) ); - - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION ); - return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION ); - } - - ssl->handshake->max_major_ver = buf[3]; - ssl->handshake->max_minor_ver = buf[4]; - - if( ( ret = mbedtls_ssl_fetch_input( ssl, 2 + n ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); - return( ret ); - } - - ssl->handshake->update_checksum( ssl, buf + 2, n ); - - buf = ssl->in_msg; - n = ssl->in_left - 5; - - /* - * 0 . 1 ciphersuitelist length - * 2 . 3 session id length - * 4 . 5 challenge length - * 6 . .. ciphersuitelist - * .. . .. session id - * .. . .. challenge - */ - MBEDTLS_SSL_DEBUG_BUF( 4, "record contents", buf, n ); - - ciph_len = ( buf[0] << 8 ) | buf[1]; - sess_len = ( buf[2] << 8 ) | buf[3]; - chal_len = ( buf[4] << 8 ) | buf[5]; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciph_len: %d, sess_len: %d, chal_len: %d", - ciph_len, sess_len, chal_len ) ); - - /* - * Make sure each parameter length is valid - */ - if( ciph_len < 3 || ( ciph_len % 3 ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - if( sess_len > 32 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - if( chal_len < 8 || chal_len > 32 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - if( n != 6 + ciph_len + sess_len + chal_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, ciphersuitelist", - buf + 6, ciph_len ); - MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, session id", - buf + 6 + ciph_len, sess_len ); - MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, challenge", - buf + 6 + ciph_len + sess_len, chal_len ); - - p = buf + 6 + ciph_len; - ssl->session_negotiate->id_len = sess_len; - memset( ssl->session_negotiate->id, 0, - sizeof( ssl->session_negotiate->id ) ); - memcpy( ssl->session_negotiate->id, p, ssl->session_negotiate->id_len ); - - p += sess_len; - memset( ssl->handshake->randbytes, 0, 64 ); - memcpy( ssl->handshake->randbytes + 32 - chal_len, p, chal_len ); - - /* - * Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV - */ - for( i = 0, p = buf + 6; i < ciph_len; i += 3, p += 3 ) - { - if( p[0] == 0 && p[1] == 0 && p[2] == MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "received TLS_EMPTY_RENEGOTIATION_INFO " ) ); -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "received RENEGOTIATION SCSV " - "during renegotiation" ) ); - - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION; - break; - } - } - -#if defined(MBEDTLS_SSL_FALLBACK_SCSV) - for( i = 0, p = buf + 6; i < ciph_len; i += 3, p += 3 ) - { - if( p[0] == 0 && - p[1] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 ) & 0xff ) && - p[2] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE ) & 0xff ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "received FALLBACK_SCSV" ) ); - - if( ssl->minor_ver < ssl->conf->max_minor_ver ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "inapropriate fallback" ) ); - - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_INAPROPRIATE_FALLBACK ); - - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - break; - } - } -#endif /* MBEDTLS_SSL_FALLBACK_SCSV */ - - got_common_suite = 0; - ciphersuites = ssl->conf->ciphersuite_list[ssl->minor_ver]; - ciphersuite_info = NULL; -#if defined(MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE) - for( j = 0, p = buf + 6; j < ciph_len; j += 3, p += 3 ) - for( i = 0; ciphersuites[i] != 0; i++ ) -#else - for( i = 0; ciphersuites[i] != 0; i++ ) - for( j = 0, p = buf + 6; j < ciph_len; j += 3, p += 3 ) -#endif - { - if( p[0] != 0 || - p[1] != ( ( ciphersuites[i] >> 8 ) & 0xFF ) || - p[2] != ( ( ciphersuites[i] ) & 0xFF ) ) - continue; - - got_common_suite = 1; - - if( ( ret = ssl_ciphersuite_match( ssl, ciphersuites[i], - &ciphersuite_info ) ) != 0 ) - return( ret ); - - if( ciphersuite_info != NULL ) - goto have_ciphersuite_v2; - } - - if( got_common_suite ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "got ciphersuites in common, " - "but none of them usable" ) ); - return( MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE ); - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) ); - return( MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN ); - } - -have_ciphersuite_v2: - MBEDTLS_SSL_DEBUG_MSG( 2, ( "selected ciphersuite: %s", ciphersuite_info->name ) ); - - ssl->session_negotiate->ciphersuite = ciphersuites[i]; - ssl->transform_negotiate->ciphersuite_info = ciphersuite_info; - - /* - * SSLv2 Client Hello relevant renegotiation security checks - */ - if( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && - ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - ssl->in_left = 0; - ssl->state++; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse client hello v2" ) ); - - return( 0 ); -} -#endif /* MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO */ - -/* This function doesn't alert on errors that happen early during - ClientHello parsing because they might indicate that the client is - not talking SSL/TLS at all and would not understand our alert. */ -static int ssl_parse_client_hello( mbedtls_ssl_context *ssl ) -{ - int ret, got_common_suite; - size_t i, j; - size_t ciph_offset, comp_offset, ext_offset; - size_t msg_len, ciph_len, sess_len, comp_len, ext_len; -#if defined(MBEDTLS_SSL_PROTO_DTLS) - size_t cookie_offset, cookie_len; -#endif - unsigned char *buf, *p, *ext; -#if defined(MBEDTLS_SSL_RENEGOTIATION) - int renegotiation_info_seen = 0; -#endif - int handshake_failure = 0; - const int *ciphersuites; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info; - int major, minor; - - /* If there is no signature-algorithm extension present, - * we need to fall back to the default values for allowed - * signature-hash pairs. */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) - int sig_hash_alg_ext_present = 0; -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && - MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client hello" ) ); - -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) -read_record_header: -#endif - /* - * If renegotiating, then the input was read with mbedtls_ssl_read_record(), - * otherwise read it ourselves manually in order to support SSLv2 - * ClientHello, which doesn't use the same record layer format. - */ -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE ) -#endif - { - if( ( ret = mbedtls_ssl_fetch_input( ssl, 5 ) ) != 0 ) - { - /* No alert on a read error. */ - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); - return( ret ); - } - } - - buf = ssl->in_hdr; - -#if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO) -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_STREAM ) -#endif - if( ( buf[0] & 0x80 ) != 0 ) - return( ssl_parse_client_hello_v2( ssl ) ); -#endif - - MBEDTLS_SSL_DEBUG_BUF( 4, "record header", buf, mbedtls_ssl_hdr_len( ssl ) ); - - /* - * SSLv3/TLS Client Hello - * - * Record layer: - * 0 . 0 message type - * 1 . 2 protocol version - * 3 . 11 DTLS: epoch + record sequence number - * 3 . 4 message length - */ - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, message type: %d", - buf[0] ) ); - - if( buf[0] != MBEDTLS_SSL_MSG_HANDSHAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, message len.: %d", - ( ssl->in_len[0] << 8 ) | ssl->in_len[1] ) ); - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, protocol version: [%d:%d]", - buf[1], buf[2] ) ); - - mbedtls_ssl_read_version( &major, &minor, ssl->conf->transport, buf + 1 ); - - /* According to RFC 5246 Appendix E.1, the version here is typically - * "{03,00}, the lowest version number supported by the client, [or] the - * value of ClientHello.client_version", so the only meaningful check here - * is the major version shouldn't be less than 3 */ - if( major < MBEDTLS_SSL_MAJOR_VERSION_3 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - /* For DTLS if this is the initial handshake, remember the client sequence - * number to use it in our next message (RFC 6347 4.2.1) */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM -#if defined(MBEDTLS_SSL_RENEGOTIATION) - && ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE -#endif - ) - { - /* Epoch should be 0 for initial handshakes */ - if( ssl->in_ctr[0] != 0 || ssl->in_ctr[1] != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - memcpy( ssl->cur_out_ctr + 2, ssl->in_ctr + 2, 6 ); - -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) - if( mbedtls_ssl_dtls_replay_check( ssl ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "replayed record, discarding" ) ); - ssl->next_record_offset = 0; - ssl->in_left = 0; - goto read_record_header; - } - - /* No MAC to check yet, so we can update right now */ - mbedtls_ssl_dtls_replay_update( ssl ); -#endif - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - msg_len = ( ssl->in_len[0] << 8 ) | ssl->in_len[1]; - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ) - { - /* Set by mbedtls_ssl_read_record() */ - msg_len = ssl->in_hslen; - } - else -#endif - { - if( msg_len > MBEDTLS_SSL_IN_CONTENT_LEN ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - if( ( ret = mbedtls_ssl_fetch_input( ssl, - mbedtls_ssl_hdr_len( ssl ) + msg_len ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); - return( ret ); - } - - /* Done reading this record, get ready for the next one */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - ssl->next_record_offset = msg_len + mbedtls_ssl_hdr_len( ssl ); - else -#endif - ssl->in_left = 0; - } - - buf = ssl->in_msg; - - MBEDTLS_SSL_DEBUG_BUF( 4, "record contents", buf, msg_len ); - - ssl->handshake->update_checksum( ssl, buf, msg_len ); - - /* - * Handshake layer: - * 0 . 0 handshake type - * 1 . 3 handshake length - * 4 . 5 DTLS only: message seqence number - * 6 . 8 DTLS only: fragment offset - * 9 . 11 DTLS only: fragment length - */ - if( msg_len < mbedtls_ssl_hs_hdr_len( ssl ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, handshake type: %d", buf[0] ) ); - - if( buf[0] != MBEDTLS_SSL_HS_CLIENT_HELLO ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, handshake len.: %d", - ( buf[1] << 16 ) | ( buf[2] << 8 ) | buf[3] ) ); - - /* We don't support fragmentation of ClientHello (yet?) */ - if( buf[1] != 0 || - msg_len != mbedtls_ssl_hs_hdr_len( ssl ) + ( ( buf[2] << 8 ) | buf[3] ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - /* - * Copy the client's handshake message_seq on initial handshakes, - * check sequence number on renego. - */ -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) - { - /* This couldn't be done in ssl_prepare_handshake_record() */ - unsigned int cli_msg_seq = ( ssl->in_msg[4] << 8 ) | - ssl->in_msg[5]; - - if( cli_msg_seq != ssl->handshake->in_msg_seq ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message_seq: " - "%d (expected %d)", cli_msg_seq, - ssl->handshake->in_msg_seq ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - ssl->handshake->in_msg_seq++; - } - else -#endif - { - unsigned int cli_msg_seq = ( ssl->in_msg[4] << 8 ) | - ssl->in_msg[5]; - ssl->handshake->out_msg_seq = cli_msg_seq; - ssl->handshake->in_msg_seq = cli_msg_seq + 1; - } - - /* - * For now we don't support fragmentation, so make sure - * fragment_offset == 0 and fragment_length == length - */ - if( ssl->in_msg[6] != 0 || ssl->in_msg[7] != 0 || ssl->in_msg[8] != 0 || - memcmp( ssl->in_msg + 1, ssl->in_msg + 9, 3 ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "ClientHello fragmentation not supported" ) ); - return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); - } - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - buf += mbedtls_ssl_hs_hdr_len( ssl ); - msg_len -= mbedtls_ssl_hs_hdr_len( ssl ); - - /* - * ClientHello layer: - * 0 . 1 protocol version - * 2 . 33 random bytes (starting with 4 bytes of Unix time) - * 34 . 35 session id length (1 byte) - * 35 . 34+x session id - * 35+x . 35+x DTLS only: cookie length (1 byte) - * 36+x . .. DTLS only: cookie - * .. . .. ciphersuite list length (2 bytes) - * .. . .. ciphersuite list - * .. . .. compression alg. list length (1 byte) - * .. . .. compression alg. list - * .. . .. extensions length (2 bytes, optional) - * .. . .. extensions (optional) - */ - - /* - * Minimal length (with everything empty and extensions omitted) is - * 2 + 32 + 1 + 2 + 1 = 38 bytes. Check that first, so that we can - * read at least up to session id length without worrying. - */ - if( msg_len < 38 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - /* - * Check and save the protocol version - */ - MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, version", buf, 2 ); - - mbedtls_ssl_read_version( &ssl->major_ver, &ssl->minor_ver, - ssl->conf->transport, buf ); - - ssl->handshake->max_major_ver = ssl->major_ver; - ssl->handshake->max_minor_ver = ssl->minor_ver; - - if( ssl->major_ver < ssl->conf->min_major_ver || - ssl->minor_ver < ssl->conf->min_minor_ver ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "client only supports ssl smaller than minimum" - " [%d:%d] < [%d:%d]", - ssl->major_ver, ssl->minor_ver, - ssl->conf->min_major_ver, ssl->conf->min_minor_ver ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION ); - return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION ); - } - - if( ssl->major_ver > ssl->conf->max_major_ver ) - { - ssl->major_ver = ssl->conf->max_major_ver; - ssl->minor_ver = ssl->conf->max_minor_ver; - } - else if( ssl->minor_ver > ssl->conf->max_minor_ver ) - ssl->minor_ver = ssl->conf->max_minor_ver; - - /* - * Save client random (inc. Unix time) - */ - MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, random bytes", buf + 2, 32 ); - - memcpy( ssl->handshake->randbytes, buf + 2, 32 ); - - /* - * Check the session ID length and save session ID - */ - sess_len = buf[34]; - - if( sess_len > sizeof( ssl->session_negotiate->id ) || - sess_len + 34 + 2 > msg_len ) /* 2 for cipherlist length field */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, session id", buf + 35, sess_len ); - - ssl->session_negotiate->id_len = sess_len; - memset( ssl->session_negotiate->id, 0, - sizeof( ssl->session_negotiate->id ) ); - memcpy( ssl->session_negotiate->id, buf + 35, - ssl->session_negotiate->id_len ); - - /* - * Check the cookie length and content - */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - cookie_offset = 35 + sess_len; - cookie_len = buf[cookie_offset]; - - if( cookie_offset + 1 + cookie_len + 2 > msg_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, cookie", - buf + cookie_offset + 1, cookie_len ); - -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) - if( ssl->conf->f_cookie_check != NULL -#if defined(MBEDTLS_SSL_RENEGOTIATION) - && ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE -#endif - ) - { - if( ssl->conf->f_cookie_check( ssl->conf->p_cookie, - buf + cookie_offset + 1, cookie_len, - ssl->cli_id, ssl->cli_id_len ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "cookie verification failed" ) ); - ssl->handshake->verify_cookie_len = 1; - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "cookie verification passed" ) ); - ssl->handshake->verify_cookie_len = 0; - } - } - else -#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ - { - /* We know we didn't send a cookie, so it should be empty */ - if( cookie_len != 0 ) - { - /* This may be an attacker's probe, so don't send an alert */ - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "cookie verification skipped" ) ); - } - - /* - * Check the ciphersuitelist length (will be parsed later) - */ - ciph_offset = cookie_offset + 1 + cookie_len; - } - else -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - ciph_offset = 35 + sess_len; - - ciph_len = ( buf[ciph_offset + 0] << 8 ) - | ( buf[ciph_offset + 1] ); - - if( ciph_len < 2 || - ciph_len + 2 + ciph_offset + 1 > msg_len || /* 1 for comp. alg. len */ - ( ciph_len % 2 ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, ciphersuitelist", - buf + ciph_offset + 2, ciph_len ); - - /* - * Check the compression algorithms length and pick one - */ - comp_offset = ciph_offset + 2 + ciph_len; - - comp_len = buf[comp_offset]; - - if( comp_len < 1 || - comp_len > 16 || - comp_len + comp_offset + 1 > msg_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, compression", - buf + comp_offset + 1, comp_len ); - - ssl->session_negotiate->compression = MBEDTLS_SSL_COMPRESS_NULL; -#if defined(MBEDTLS_ZLIB_SUPPORT) - for( i = 0; i < comp_len; ++i ) - { - if( buf[comp_offset + 1 + i] == MBEDTLS_SSL_COMPRESS_DEFLATE ) - { - ssl->session_negotiate->compression = MBEDTLS_SSL_COMPRESS_DEFLATE; - break; - } - } -#endif - - /* See comments in ssl_write_client_hello() */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - ssl->session_negotiate->compression = MBEDTLS_SSL_COMPRESS_NULL; -#endif - - /* Do not parse the extensions if the protocol is SSLv3 */ -#if defined(MBEDTLS_SSL_PROTO_SSL3) - if( ( ssl->major_ver != 3 ) || ( ssl->minor_ver != 0 ) ) - { -#endif - /* - * Check the extension length - */ - ext_offset = comp_offset + 1 + comp_len; - if( msg_len > ext_offset ) - { - if( msg_len < ext_offset + 2 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - ext_len = ( buf[ext_offset + 0] << 8 ) - | ( buf[ext_offset + 1] ); - - if( ( ext_len > 0 && ext_len < 4 ) || - msg_len != ext_offset + 2 + ext_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - } - else - ext_len = 0; - - ext = buf + ext_offset + 2; - MBEDTLS_SSL_DEBUG_BUF( 3, "client hello extensions", ext, ext_len ); - - while( ext_len != 0 ) - { - unsigned int ext_id; - unsigned int ext_size; - if ( ext_len < 4 ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - ext_id = ( ( ext[0] << 8 ) | ( ext[1] ) ); - ext_size = ( ( ext[2] << 8 ) | ( ext[3] ) ); - - if( ext_size + 4 > ext_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - switch( ext_id ) - { -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - case MBEDTLS_TLS_EXT_SERVERNAME: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ServerName extension" ) ); - if( ssl->conf->f_sni == NULL ) - break; - - ret = ssl_parse_servername_ext( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - break; -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ - - case MBEDTLS_TLS_EXT_RENEGOTIATION_INFO: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) ); -#if defined(MBEDTLS_SSL_RENEGOTIATION) - renegotiation_info_seen = 1; -#endif - - ret = ssl_parse_renegotiation_info( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - break; - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) - case MBEDTLS_TLS_EXT_SIG_ALG: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found signature_algorithms extension" ) ); - - ret = ssl_parse_signature_algorithms_ext( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - - sig_hash_alg_ext_present = 1; - break; -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && - MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ - -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - case MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported elliptic curves extension" ) ); - - ret = ssl_parse_supported_elliptic_curves( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - break; - - case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported point formats extension" ) ); - ssl->handshake->cli_exts |= MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT; - - ret = ssl_parse_supported_point_formats( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - break; -#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || - MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - case MBEDTLS_TLS_EXT_ECJPAKE_KKPP: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ecjpake kkpp extension" ) ); - - ret = ssl_parse_ecjpake_kkpp( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - break; -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found max fragment length extension" ) ); - - ret = ssl_parse_max_fragment_length_ext( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - break; -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) - case MBEDTLS_TLS_EXT_TRUNCATED_HMAC: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found truncated hmac extension" ) ); - - ret = ssl_parse_truncated_hmac_ext( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - break; -#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found encrypt then mac extension" ) ); - - ret = ssl_parse_encrypt_then_mac_ext( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - break; -#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found extended master secret extension" ) ); - - ret = ssl_parse_extended_ms_ext( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - break; -#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - case MBEDTLS_TLS_EXT_SESSION_TICKET: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found session ticket extension" ) ); - - ret = ssl_parse_session_ticket_ext( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - break; -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -#if defined(MBEDTLS_SSL_ALPN) - case MBEDTLS_TLS_EXT_ALPN: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found alpn extension" ) ); - - ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - break; -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - - default: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)", - ext_id ) ); - } - - ext_len -= 4 + ext_size; - ext += 4 + ext_size; - - if( ext_len > 0 && ext_len < 4 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - } -#if defined(MBEDTLS_SSL_PROTO_SSL3) - } -#endif - -#if defined(MBEDTLS_SSL_FALLBACK_SCSV) - for( i = 0, p = buf + ciph_offset + 2; i < ciph_len; i += 2, p += 2 ) - { - if( p[0] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 ) & 0xff ) && - p[1] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE ) & 0xff ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "received FALLBACK_SCSV" ) ); - - if( ssl->minor_ver < ssl->conf->max_minor_ver ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "inapropriate fallback" ) ); - - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_INAPROPRIATE_FALLBACK ); - - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - break; - } - } -#endif /* MBEDTLS_SSL_FALLBACK_SCSV */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) - - /* - * Try to fall back to default hash SHA1 if the client - * hasn't provided any preferred signature-hash combinations. - */ - if( sig_hash_alg_ext_present == 0 ) - { - mbedtls_md_type_t md_default = MBEDTLS_MD_SHA1; - - if( mbedtls_ssl_check_sig_hash( ssl, md_default ) != 0 ) - md_default = MBEDTLS_MD_NONE; - - mbedtls_ssl_sig_hash_set_const_hash( &ssl->handshake->hash_algs, md_default ); - } - -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && - MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ - - /* - * Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV - */ - for( i = 0, p = buf + ciph_offset + 2; i < ciph_len; i += 2, p += 2 ) - { - if( p[0] == 0 && p[1] == MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "received TLS_EMPTY_RENEGOTIATION_INFO " ) ); -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "received RENEGOTIATION SCSV " - "during renegotiation" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } -#endif - ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION; - break; - } - } - - /* - * Renegotiation security checks - */ - if( ssl->secure_renegotiation != MBEDTLS_SSL_SECURE_RENEGOTIATION && - ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) ); - handshake_failure = 1; - } -#if defined(MBEDTLS_SSL_RENEGOTIATION) - else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && - ssl->secure_renegotiation == MBEDTLS_SSL_SECURE_RENEGOTIATION && - renegotiation_info_seen == 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension missing (secure)" ) ); - handshake_failure = 1; - } - else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && - ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && - ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation not allowed" ) ); - handshake_failure = 1; - } - else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && - ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && - renegotiation_info_seen == 1 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension present (legacy)" ) ); - handshake_failure = 1; - } -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - - if( handshake_failure == 1 ) - { - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - /* - * Search for a matching ciphersuite - * (At the end because we need information from the EC-based extensions - * and certificate from the SNI callback triggered by the SNI extension.) - */ - got_common_suite = 0; - ciphersuites = ssl->conf->ciphersuite_list[ssl->minor_ver]; - ciphersuite_info = NULL; -#if defined(MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE) - for( j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2 ) - for( i = 0; ciphersuites[i] != 0; i++ ) -#else - for( i = 0; ciphersuites[i] != 0; i++ ) - for( j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2 ) -#endif - { - if( p[0] != ( ( ciphersuites[i] >> 8 ) & 0xFF ) || - p[1] != ( ( ciphersuites[i] ) & 0xFF ) ) - continue; - - got_common_suite = 1; - - if( ( ret = ssl_ciphersuite_match( ssl, ciphersuites[i], - &ciphersuite_info ) ) != 0 ) - return( ret ); - - if( ciphersuite_info != NULL ) - goto have_ciphersuite; - } - - if( got_common_suite ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "got ciphersuites in common, " - "but none of them usable" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE ); - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); - return( MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN ); - } - -have_ciphersuite: - MBEDTLS_SSL_DEBUG_MSG( 2, ( "selected ciphersuite: %s", ciphersuite_info->name ) ); - - ssl->session_negotiate->ciphersuite = ciphersuites[i]; - ssl->transform_negotiate->ciphersuite_info = ciphersuite_info; - - ssl->state++; - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - mbedtls_ssl_recv_flight_completed( ssl ); -#endif - - /* Debugging-only output for testsuite */ -#if defined(MBEDTLS_DEBUG_C) && \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) - { - mbedtls_pk_type_t sig_alg = mbedtls_ssl_get_ciphersuite_sig_alg( ciphersuite_info ); - if( sig_alg != MBEDTLS_PK_NONE ) - { - mbedtls_md_type_t md_alg = mbedtls_ssl_sig_hash_set_find( &ssl->handshake->hash_algs, - sig_alg ); - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext: %d", - mbedtls_ssl_hash_from_md_alg( md_alg ) ) ); - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "no hash algorithm for signature algorithm " - "%d - should not happen", sig_alg ) ); - } - } -#endif - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse client hello" ) ); - - return( 0 ); -} - -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) -static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen ) -{ - unsigned char *p = buf; - - if( ssl->session_negotiate->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED ) - { - *olen = 0; - return; - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding truncated hmac extension" ) ); - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC ) & 0xFF ); - - *p++ = 0x00; - *p++ = 0x00; - - *olen = 4; -} -#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) -static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen ) -{ - unsigned char *p = buf; - const mbedtls_ssl_ciphersuite_t *suite = NULL; - const mbedtls_cipher_info_t *cipher = NULL; - - if( ssl->session_negotiate->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED || - ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) - { - *olen = 0; - return; - } - - /* - * RFC 7366: "If a server receives an encrypt-then-MAC request extension - * from a client and then selects a stream or Authenticated Encryption - * with Associated Data (AEAD) ciphersuite, it MUST NOT send an - * encrypt-then-MAC response extension back to the client." - */ - if( ( suite = mbedtls_ssl_ciphersuite_from_id( - ssl->session_negotiate->ciphersuite ) ) == NULL || - ( cipher = mbedtls_cipher_info_from_type( suite->cipher ) ) == NULL || - cipher->mode != MBEDTLS_MODE_CBC ) - { - *olen = 0; - return; - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding encrypt then mac extension" ) ); - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC ) & 0xFF ); - - *p++ = 0x00; - *p++ = 0x00; - - *olen = 4; -} -#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) -static void ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen ) -{ - unsigned char *p = buf; - - if( ssl->handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED || - ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) - { - *olen = 0; - return; - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding extended master secret " - "extension" ) ); - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET ) & 0xFF ); - - *p++ = 0x00; - *p++ = 0x00; - - *olen = 4; -} -#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) -static void ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen ) -{ - unsigned char *p = buf; - - if( ssl->handshake->new_session_ticket == 0 ) - { - *olen = 0; - return; - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding session ticket extension" ) ); - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET ) & 0xFF ); - - *p++ = 0x00; - *p++ = 0x00; - - *olen = 4; -} -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen ) -{ - unsigned char *p = buf; - - if( ssl->secure_renegotiation != MBEDTLS_SSL_SECURE_RENEGOTIATION ) - { - *olen = 0; - return; - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, secure renegotiation extension" ) ); - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO ) & 0xFF ); - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ) - { - *p++ = 0x00; - *p++ = ( ssl->verify_data_len * 2 + 1 ) & 0xFF; - *p++ = ssl->verify_data_len * 2 & 0xFF; - - memcpy( p, ssl->peer_verify_data, ssl->verify_data_len ); - p += ssl->verify_data_len; - memcpy( p, ssl->own_verify_data, ssl->verify_data_len ); - p += ssl->verify_data_len; - } - else -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - { - *p++ = 0x00; - *p++ = 0x01; - *p++ = 0x00; - } - - *olen = p - buf; -} - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) -static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen ) -{ - unsigned char *p = buf; - - if( ssl->session_negotiate->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE ) - { - *olen = 0; - return; - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, max_fragment_length extension" ) ); - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH ) & 0xFF ); - - *p++ = 0x00; - *p++ = 1; - - *p++ = ssl->session_negotiate->mfl_code; - - *olen = 5; -} -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen ) -{ - unsigned char *p = buf; - ((void) ssl); - - if( ( ssl->handshake->cli_exts & - MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT ) == 0 ) - { - *olen = 0; - return; - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, supported_point_formats extension" ) ); - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS ) & 0xFF ); - - *p++ = 0x00; - *p++ = 2; - - *p++ = 1; - *p++ = MBEDTLS_ECP_PF_UNCOMPRESSED; - - *olen = 6; -} -#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, - size_t *olen ) -{ - int ret; - unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; - size_t kkpp_len; - - *olen = 0; - - /* Skip costly computation if not needed */ - if( ssl->transform_negotiate->ciphersuite_info->key_exchange != - MBEDTLS_KEY_EXCHANGE_ECJPAKE ) - return; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, ecjpake kkpp extension" ) ); - - if( end - p < 4 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); - return; - } - - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP ) & 0xFF ); - - ret = mbedtls_ecjpake_write_round_one( &ssl->handshake->ecjpake_ctx, - p + 2, end - p - 2, &kkpp_len, - ssl->conf->f_rng, ssl->conf->p_rng ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1 , "mbedtls_ecjpake_write_round_one", ret ); - return; - } - - *p++ = (unsigned char)( ( kkpp_len >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( kkpp_len ) & 0xFF ); - - *olen = kkpp_len + 4; -} -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_SSL_ALPN ) -static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl, - unsigned char *buf, size_t *olen ) -{ - if( ssl->alpn_chosen == NULL ) - { - *olen = 0; - return; - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding alpn extension" ) ); - - /* - * 0 . 1 ext identifier - * 2 . 3 ext length - * 4 . 5 protocol list length - * 6 . 6 protocol name length - * 7 . 7+n protocol name - */ - buf[0] = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN >> 8 ) & 0xFF ); - buf[1] = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN ) & 0xFF ); - - *olen = 7 + strlen( ssl->alpn_chosen ); - - buf[2] = (unsigned char)( ( ( *olen - 4 ) >> 8 ) & 0xFF ); - buf[3] = (unsigned char)( ( ( *olen - 4 ) ) & 0xFF ); - - buf[4] = (unsigned char)( ( ( *olen - 6 ) >> 8 ) & 0xFF ); - buf[5] = (unsigned char)( ( ( *olen - 6 ) ) & 0xFF ); - - buf[6] = (unsigned char)( ( ( *olen - 7 ) ) & 0xFF ); - - memcpy( buf + 7, ssl->alpn_chosen, *olen - 7 ); -} -#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */ - -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) -static int ssl_write_hello_verify_request( mbedtls_ssl_context *ssl ) -{ - int ret; - unsigned char *p = ssl->out_msg + 4; - unsigned char *cookie_len_byte; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write hello verify request" ) ); - - /* - * struct { - * ProtocolVersion server_version; - * opaque cookie<0..2^8-1>; - * } HelloVerifyRequest; - */ - - /* The RFC is not clear on this point, but sending the actual negotiated - * version looks like the most interoperable thing to do. */ - mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver, - ssl->conf->transport, p ); - MBEDTLS_SSL_DEBUG_BUF( 3, "server version", p, 2 ); - p += 2; - - /* If we get here, f_cookie_check is not null */ - if( ssl->conf->f_cookie_write == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "inconsistent cookie callbacks" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - /* Skip length byte until we know the length */ - cookie_len_byte = p++; - - if( ( ret = ssl->conf->f_cookie_write( ssl->conf->p_cookie, - &p, ssl->out_buf + MBEDTLS_SSL_OUT_BUFFER_LEN, - ssl->cli_id, ssl->cli_id_len ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "f_cookie_write", ret ); - return( ret ); - } - - *cookie_len_byte = (unsigned char)( p - ( cookie_len_byte + 1 ) ); - - MBEDTLS_SSL_DEBUG_BUF( 3, "cookie sent", cookie_len_byte + 1, *cookie_len_byte ); - - ssl->out_msglen = p - ssl->out_msg; - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST; - - ssl->state = MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT; - - if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); - return( ret ); - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret ); - return( ret ); - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write hello verify request" ) ); - - return( 0 ); -} -#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ - -static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) -{ -#if defined(MBEDTLS_HAVE_TIME) - mbedtls_time_t t; -#endif - int ret; - size_t olen, ext_len = 0, n; - unsigned char *buf, *p; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server hello" ) ); - -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl->handshake->verify_cookie_len != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "client hello was not authenticated" ) ); - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server hello" ) ); - - return( ssl_write_hello_verify_request( ssl ) ); - } -#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ - - if( ssl->conf->f_rng == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "no RNG provided") ); - return( MBEDTLS_ERR_SSL_NO_RNG ); - } - - /* - * 0 . 0 handshake type - * 1 . 3 handshake length - * 4 . 5 protocol version - * 6 . 9 UNIX time() - * 10 . 37 random bytes - */ - buf = ssl->out_msg; - p = buf + 4; - - mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver, - ssl->conf->transport, p ); - p += 2; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen version: [%d:%d]", - buf[4], buf[5] ) ); - -#if defined(MBEDTLS_HAVE_TIME) - t = mbedtls_time( NULL ); - *p++ = (unsigned char)( t >> 24 ); - *p++ = (unsigned char)( t >> 16 ); - *p++ = (unsigned char)( t >> 8 ); - *p++ = (unsigned char)( t ); - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", t ) ); -#else - if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 4 ) ) != 0 ) - return( ret ); - - p += 4; -#endif /* MBEDTLS_HAVE_TIME */ - - if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 28 ) ) != 0 ) - return( ret ); - - p += 28; - - memcpy( ssl->handshake->randbytes + 32, buf + 6, 32 ); - - MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, random bytes", buf + 6, 32 ); - - /* - * Resume is 0 by default, see ssl_handshake_init(). - * It may be already set to 1 by ssl_parse_session_ticket_ext(). - * If not, try looking up session ID in our cache. - */ - if( ssl->handshake->resume == 0 && -#if defined(MBEDTLS_SSL_RENEGOTIATION) - ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE && -#endif - ssl->session_negotiate->id_len != 0 && - ssl->conf->f_get_cache != NULL && - ssl->conf->f_get_cache( ssl->conf->p_cache, ssl->session_negotiate ) == 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "session successfully restored from cache" ) ); - ssl->handshake->resume = 1; - } - - if( ssl->handshake->resume == 0 ) - { - /* - * New session, create a new session id, - * unless we're about to issue a session ticket - */ - ssl->state++; - -#if defined(MBEDTLS_HAVE_TIME) - ssl->session_negotiate->start = mbedtls_time( NULL ); -#endif - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - if( ssl->handshake->new_session_ticket != 0 ) - { - ssl->session_negotiate->id_len = n = 0; - memset( ssl->session_negotiate->id, 0, 32 ); - } - else -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - { - ssl->session_negotiate->id_len = n = 32; - if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->session_negotiate->id, - n ) ) != 0 ) - return( ret ); - } - } - else - { - /* - * Resuming a session - */ - n = ssl->session_negotiate->id_len; - ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC; - - if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret ); - return( ret ); - } - } - - /* - * 38 . 38 session id length - * 39 . 38+n session id - * 39+n . 40+n chosen ciphersuite - * 41+n . 41+n chosen compression alg. - * 42+n . 43+n extensions length - * 44+n . 43+n+m extensions - */ - *p++ = (unsigned char) ssl->session_negotiate->id_len; - memcpy( p, ssl->session_negotiate->id, ssl->session_negotiate->id_len ); - p += ssl->session_negotiate->id_len; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) ); - MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, session id", buf + 39, n ); - MBEDTLS_SSL_DEBUG_MSG( 3, ( "%s session has been resumed", - ssl->handshake->resume ? "a" : "no" ) ); - - *p++ = (unsigned char)( ssl->session_negotiate->ciphersuite >> 8 ); - *p++ = (unsigned char)( ssl->session_negotiate->ciphersuite ); - *p++ = (unsigned char)( ssl->session_negotiate->compression ); - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %s", - mbedtls_ssl_get_ciphersuite_name( ssl->session_negotiate->ciphersuite ) ) ); - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: 0x%02X", - ssl->session_negotiate->compression ) ); - - /* Do not write the extensions if the protocol is SSLv3 */ -#if defined(MBEDTLS_SSL_PROTO_SSL3) - if( ( ssl->major_ver != 3 ) || ( ssl->minor_ver != 0 ) ) - { -#endif - - /* - * First write extensions, then the total length - */ - ssl_write_renegotiation_ext( ssl, p + 2 + ext_len, &olen ); - ext_len += olen; - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - ssl_write_max_fragment_length_ext( ssl, p + 2 + ext_len, &olen ); - ext_len += olen; -#endif - -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) - ssl_write_truncated_hmac_ext( ssl, p + 2 + ext_len, &olen ); - ext_len += olen; -#endif - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - ssl_write_encrypt_then_mac_ext( ssl, p + 2 + ext_len, &olen ); - ext_len += olen; -#endif - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - ssl_write_extended_ms_ext( ssl, p + 2 + ext_len, &olen ); - ext_len += olen; -#endif - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - ssl_write_session_ticket_ext( ssl, p + 2 + ext_len, &olen ); - ext_len += olen; -#endif - -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - if ( mbedtls_ssl_ciphersuite_uses_ec( - mbedtls_ssl_ciphersuite_from_id( ssl->session_negotiate->ciphersuite ) ) ) - { - ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len, &olen ); - ext_len += olen; - } -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - ssl_write_ecjpake_kkpp_ext( ssl, p + 2 + ext_len, &olen ); - ext_len += olen; -#endif - -#if defined(MBEDTLS_SSL_ALPN) - ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen ); - ext_len += olen; -#endif - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, total extension length: %d", ext_len ) ); - - if( ext_len > 0 ) - { - *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( ext_len ) & 0xFF ); - p += ext_len; - } - -#if defined(MBEDTLS_SSL_PROTO_SSL3) - } -#endif - - ssl->out_msglen = p - buf; - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_HELLO; - - ret = mbedtls_ssl_write_handshake_msg( ssl ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server hello" ) ); - - return( ret ); -} - -#if !defined(MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED) -static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) -{ - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->transform_negotiate->ciphersuite_info; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate request" ) ); - - if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) ); - ssl->state++; - return( 0 ); - } - - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); -} -#else /* !MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */ -static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) -{ - int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->transform_negotiate->ciphersuite_info; - size_t dn_size, total_dn_size; /* excluding length bytes */ - size_t ct_len, sa_len; /* including length bytes */ - unsigned char *buf, *p; - const unsigned char * const end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; - const mbedtls_x509_crt *crt; - int authmode; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate request" ) ); - - ssl->state++; - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - if( ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET ) - authmode = ssl->handshake->sni_authmode; - else -#endif - authmode = ssl->conf->authmode; - - if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) || - authmode == MBEDTLS_SSL_VERIFY_NONE ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) ); - return( 0 ); - } - - /* - * 0 . 0 handshake type - * 1 . 3 handshake length - * 4 . 4 cert type count - * 5 .. m-1 cert types - * m .. m+1 sig alg length (TLS 1.2 only) - * m+1 .. n-1 SignatureAndHashAlgorithms (TLS 1.2 only) - * n .. n+1 length of all DNs - * n+2 .. n+3 length of DN 1 - * n+4 .. ... Distinguished Name #1 - * ... .. ... length of DN 2, etc. - */ - buf = ssl->out_msg; - p = buf + 4; - - /* - * Supported certificate types - * - * ClientCertificateType certificate_types<1..2^8-1>; - * enum { (255) } ClientCertificateType; - */ - ct_len = 0; - -#if defined(MBEDTLS_RSA_C) - p[1 + ct_len++] = MBEDTLS_SSL_CERT_TYPE_RSA_SIGN; -#endif -#if defined(MBEDTLS_ECDSA_C) - p[1 + ct_len++] = MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN; -#endif - - p[0] = (unsigned char) ct_len++; - p += ct_len; - - sa_len = 0; -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - /* - * Add signature_algorithms for verify (TLS 1.2) - * - * SignatureAndHashAlgorithm supported_signature_algorithms<2..2^16-2>; - * - * struct { - * HashAlgorithm hash; - * SignatureAlgorithm signature; - * } SignatureAndHashAlgorithm; - * - * enum { (255) } HashAlgorithm; - * enum { (255) } SignatureAlgorithm; - */ - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) - { - const int *cur; - - /* - * Supported signature algorithms - */ - for( cur = ssl->conf->sig_hashes; *cur != MBEDTLS_MD_NONE; cur++ ) - { - unsigned char hash = mbedtls_ssl_hash_from_md_alg( *cur ); - - if( MBEDTLS_SSL_HASH_NONE == hash || mbedtls_ssl_set_calc_verify_md( ssl, hash ) ) - continue; - -#if defined(MBEDTLS_RSA_C) - p[2 + sa_len++] = hash; - p[2 + sa_len++] = MBEDTLS_SSL_SIG_RSA; -#endif -#if defined(MBEDTLS_ECDSA_C) - p[2 + sa_len++] = hash; - p[2 + sa_len++] = MBEDTLS_SSL_SIG_ECDSA; -#endif - } - - p[0] = (unsigned char)( sa_len >> 8 ); - p[1] = (unsigned char)( sa_len ); - sa_len += 2; - p += sa_len; - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - - /* - * DistinguishedName certificate_authorities<0..2^16-1>; - * opaque DistinguishedName<1..2^16-1>; - */ - p += 2; - - total_dn_size = 0; - - if( ssl->conf->cert_req_ca_list == MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED ) - { - /* NOTE: If trusted certificates are provisioned - * via a CA callback (configured through - * `mbedtls_ssl_conf_ca_cb()`, then the - * CertificateRequest is currently left empty. */ - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - if( ssl->handshake->sni_ca_chain != NULL ) - crt = ssl->handshake->sni_ca_chain; - else -#endif - crt = ssl->conf->ca_chain; - - while( crt != NULL && crt->version != 0 ) - { - dn_size = crt->subject_raw.len; - - if( end < p || - (size_t)( end - p ) < dn_size || - (size_t)( end - p ) < 2 + dn_size ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "skipping CAs: buffer too short" ) ); - break; - } - - *p++ = (unsigned char)( dn_size >> 8 ); - *p++ = (unsigned char)( dn_size ); - memcpy( p, crt->subject_raw.p, dn_size ); - p += dn_size; - - MBEDTLS_SSL_DEBUG_BUF( 3, "requested DN", p - dn_size, dn_size ); - - total_dn_size += 2 + dn_size; - crt = crt->next; - } - } - - ssl->out_msglen = p - buf; - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE_REQUEST; - ssl->out_msg[4 + ct_len + sa_len] = (unsigned char)( total_dn_size >> 8 ); - ssl->out_msg[5 + ct_len + sa_len] = (unsigned char)( total_dn_size ); - - ret = mbedtls_ssl_write_handshake_msg( ssl ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write certificate request" ) ); - - return( ret ); -} -#endif /* MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) -static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl ) -{ - int ret; - - if( ! mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_ECKEY ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) ); - return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH ); - } - - if( ( ret = mbedtls_ecdh_get_params( &ssl->handshake->ecdh_ctx, - mbedtls_pk_ec( *mbedtls_ssl_own_key( ssl ) ), - MBEDTLS_ECDH_OURS ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_get_params" ), ret ); - return( ret ); - } - - return( 0 ); -} -#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || - MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && \ - defined(MBEDTLS_SSL_ASYNC_PRIVATE) -static int ssl_resume_server_key_exchange( mbedtls_ssl_context *ssl, - size_t *signature_len ) -{ - /* Append the signature to ssl->out_msg, leaving 2 bytes for the - * signature length which will be added in ssl_write_server_key_exchange - * after the call to ssl_prepare_server_key_exchange. - * ssl_write_server_key_exchange also takes care of incrementing - * ssl->out_msglen. */ - unsigned char *sig_start = ssl->out_msg + ssl->out_msglen + 2; - size_t sig_max_len = ( ssl->out_buf + MBEDTLS_SSL_OUT_CONTENT_LEN - - sig_start ); - int ret = ssl->conf->f_async_resume( ssl, - sig_start, signature_len, sig_max_len ); - if( ret != MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS ) - { - ssl->handshake->async_in_progress = 0; - mbedtls_ssl_set_async_operation_data( ssl, NULL ); - } - MBEDTLS_SSL_DEBUG_RET( 2, "ssl_resume_server_key_exchange", ret ); - return( ret ); -} -#endif /* defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && - defined(MBEDTLS_SSL_ASYNC_PRIVATE) */ - -/* Prepare the ServerKeyExchange message, up to and including - * calculating the signature if any, but excluding formatting the - * signature and sending the message. */ -static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, - size_t *signature_len ) -{ - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->transform_negotiate->ciphersuite_info; -#if defined(MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED) -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) - unsigned char *dig_signed = NULL; -#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ -#endif /* MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED */ - - (void) ciphersuite_info; /* unused in some configurations */ -#if !defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) - (void) signature_len; -#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ - - ssl->out_msglen = 4; /* header (type:1, length:3) to be written later */ - - /* - * - * Part 1: Provide key exchange parameters for chosen ciphersuite. - * - */ - - /* - * - ECJPAKE key exchanges - */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) - { - int ret; - size_t len = 0; - - ret = mbedtls_ecjpake_write_round_two( - &ssl->handshake->ecjpake_ctx, - ssl->out_msg + ssl->out_msglen, - MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen, &len, - ssl->conf->f_rng, ssl->conf->p_rng ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_write_round_two", ret ); - return( ret ); - } - - ssl->out_msglen += len; - } -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - - /* - * For (EC)DHE key exchanges with PSK, parameters are prefixed by support - * identity hint (RFC 4279, Sec. 3). Until someone needs this feature, - * we use empty support identity hints here. - **/ -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) - { - ssl->out_msg[ssl->out_msglen++] = 0x00; - ssl->out_msg[ssl->out_msglen++] = 0x00; - } -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ - - /* - * - DHE key exchanges - */ -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED) - if( mbedtls_ssl_ciphersuite_uses_dhe( ciphersuite_info ) ) - { - int ret; - size_t len = 0; - - if( ssl->conf->dhm_P.p == NULL || ssl->conf->dhm_G.p == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "no DH parameters set" ) ); - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - /* - * Ephemeral DH parameters: - * - * struct { - * opaque dh_p<1..2^16-1>; - * opaque dh_g<1..2^16-1>; - * opaque dh_Ys<1..2^16-1>; - * } ServerDHParams; - */ - if( ( ret = mbedtls_dhm_set_group( &ssl->handshake->dhm_ctx, - &ssl->conf->dhm_P, - &ssl->conf->dhm_G ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_set_group", ret ); - return( ret ); - } - - if( ( ret = mbedtls_dhm_make_params( - &ssl->handshake->dhm_ctx, - (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ), - ssl->out_msg + ssl->out_msglen, &len, - ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_params", ret ); - return( ret ); - } - -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) - dig_signed = ssl->out_msg + ssl->out_msglen; -#endif - - ssl->out_msglen += len; - - MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->handshake->dhm_ctx.X ); - MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P ); - MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->handshake->dhm_ctx.G ); - MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->handshake->dhm_ctx.GX ); - } -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED */ - - /* - * - ECDHE key exchanges - */ -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED) - if( mbedtls_ssl_ciphersuite_uses_ecdhe( ciphersuite_info ) ) - { - /* - * Ephemeral ECDH parameters: - * - * struct { - * ECParameters curve_params; - * ECPoint public; - * } ServerECDHParams; - */ - const mbedtls_ecp_curve_info **curve = NULL; - const mbedtls_ecp_group_id *gid; - int ret; - size_t len = 0; - - /* Match our preference list against the offered curves */ - for( gid = ssl->conf->curve_list; *gid != MBEDTLS_ECP_DP_NONE; gid++ ) - for( curve = ssl->handshake->curves; *curve != NULL; curve++ ) - if( (*curve)->grp_id == *gid ) - goto curve_matching_done; - -curve_matching_done: - if( curve == NULL || *curve == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "no matching curve for ECDHE" ) ); - return( MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDHE curve: %s", (*curve)->name ) ); - - if( ( ret = mbedtls_ecdh_setup( &ssl->handshake->ecdh_ctx, - (*curve)->grp_id ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecp_group_load", ret ); - return( ret ); - } - - if( ( ret = mbedtls_ecdh_make_params( - &ssl->handshake->ecdh_ctx, &len, - ssl->out_msg + ssl->out_msglen, - MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen, - ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_params", ret ); - return( ret ); - } - -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) - dig_signed = ssl->out_msg + ssl->out_msglen; -#endif - - ssl->out_msglen += len; - - MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, - MBEDTLS_DEBUG_ECDH_Q ); - } -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED */ - - /* - * - * Part 2: For key exchanges involving the server signing the - * exchange parameters, compute and add the signature here. - * - */ -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) - if( mbedtls_ssl_ciphersuite_uses_server_signature( ciphersuite_info ) ) - { - size_t dig_signed_len = ssl->out_msg + ssl->out_msglen - dig_signed; - size_t hashlen = 0; - unsigned char hash[MBEDTLS_MD_MAX_SIZE]; - int ret; - - /* - * 2.1: Choose hash algorithm: - * A: For TLS 1.2, obey signature-hash-algorithm extension - * to choose appropriate hash. - * B: For SSL3, TLS1.0, TLS1.1 and ECDHE_ECDSA, use SHA1 - * (RFC 4492, Sec. 5.4) - * C: Otherwise, use MD5 + SHA1 (RFC 4346, Sec. 7.4.3) - */ - - mbedtls_md_type_t md_alg; - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - mbedtls_pk_type_t sig_alg = - mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ); - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) - { - /* A: For TLS 1.2, obey signature-hash-algorithm extension - * (RFC 5246, Sec. 7.4.1.4.1). */ - if( sig_alg == MBEDTLS_PK_NONE || - ( md_alg = mbedtls_ssl_sig_hash_set_find( &ssl->handshake->hash_algs, - sig_alg ) ) == MBEDTLS_MD_NONE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - /* (... because we choose a cipher suite - * only if there is a matching hash.) */ - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - } - else -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ) - { - /* B: Default hash SHA1 */ - md_alg = MBEDTLS_MD_SHA1; - } - else -#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \ - MBEDTLS_SSL_PROTO_TLS1_1 */ - { - /* C: MD5 + SHA1 */ - md_alg = MBEDTLS_MD_NONE; - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "pick hash algorithm %d for signing", md_alg ) ); - - /* - * 2.2: Compute the hash to be signed - */ -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) - if( md_alg == MBEDTLS_MD_NONE ) - { - hashlen = 36; - ret = mbedtls_ssl_get_key_exchange_md_ssl_tls( ssl, hash, - dig_signed, - dig_signed_len ); - if( ret != 0 ) - return( ret ); - } - else -#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \ - MBEDTLS_SSL_PROTO_TLS1_1 */ -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( md_alg != MBEDTLS_MD_NONE ) - { - ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash, &hashlen, - dig_signed, - dig_signed_len, - md_alg ); - if( ret != 0 ) - return( ret ); - } - else -#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ - MBEDTLS_SSL_PROTO_TLS1_2 */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen ); - - /* - * 2.3: Compute and add the signature - */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) - { - /* - * For TLS 1.2, we need to specify signature and hash algorithm - * explicitly through a prefix to the signature. - * - * struct { - * HashAlgorithm hash; - * SignatureAlgorithm signature; - * } SignatureAndHashAlgorithm; - * - * struct { - * SignatureAndHashAlgorithm algorithm; - * opaque signature<0..2^16-1>; - * } DigitallySigned; - * - */ - - ssl->out_msg[ssl->out_msglen++] = - mbedtls_ssl_hash_from_md_alg( md_alg ); - ssl->out_msg[ssl->out_msglen++] = - mbedtls_ssl_sig_from_pk_alg( sig_alg ); - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - if( ssl->conf->f_async_sign_start != NULL ) - { - ret = ssl->conf->f_async_sign_start( ssl, - mbedtls_ssl_own_cert( ssl ), - md_alg, hash, hashlen ); - switch( ret ) - { - case MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH: - /* act as if f_async_sign was null */ - break; - case 0: - ssl->handshake->async_in_progress = 1; - return( ssl_resume_server_key_exchange( ssl, signature_len ) ); - case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS: - ssl->handshake->async_in_progress = 1; - return( MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS ); - default: - MBEDTLS_SSL_DEBUG_RET( 1, "f_async_sign_start", ret ); - return( ret ); - } - } -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - - if( mbedtls_ssl_own_key( ssl ) == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key" ) ); - return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED ); - } - - /* Append the signature to ssl->out_msg, leaving 2 bytes for the - * signature length which will be added in ssl_write_server_key_exchange - * after the call to ssl_prepare_server_key_exchange. - * ssl_write_server_key_exchange also takes care of incrementing - * ssl->out_msglen. */ - if( ( ret = mbedtls_pk_sign( mbedtls_ssl_own_key( ssl ), - md_alg, hash, hashlen, - ssl->out_msg + ssl->out_msglen + 2, - signature_len, - ssl->conf->f_rng, - ssl->conf->p_rng ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret ); - return( ret ); - } - } -#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ - - return( 0 ); -} - -/* Prepare the ServerKeyExchange message and send it. For ciphersuites - * that do not include a ServerKeyExchange message, do nothing. Either - * way, if successful, move on to the next step in the SSL state - * machine. */ -static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl ) -{ - int ret; - size_t signature_len = 0; -#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED) - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->transform_negotiate->ciphersuite_info; -#endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */ - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) ); - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED) - /* Extract static ECDH parameters and abort if ServerKeyExchange - * is not needed. */ - if( mbedtls_ssl_ciphersuite_no_pfs( ciphersuite_info ) ) - { - /* For suites involving ECDH, extract DH parameters - * from certificate at this point. */ -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED) - if( mbedtls_ssl_ciphersuite_uses_ecdh( ciphersuite_info ) ) - { - ssl_get_ecdh_params_from_cert( ssl ); - } -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED */ - - /* Key exchanges not involving ephemeral keys don't use - * ServerKeyExchange, so end here. */ - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) ); - ssl->state++; - return( 0 ); - } -#endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && \ - defined(MBEDTLS_SSL_ASYNC_PRIVATE) - /* If we have already prepared the message and there is an ongoing - * signature operation, resume signing. */ - if( ssl->handshake->async_in_progress != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "resuming signature operation" ) ); - ret = ssl_resume_server_key_exchange( ssl, &signature_len ); - } - else -#endif /* defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && - defined(MBEDTLS_SSL_ASYNC_PRIVATE) */ - { - /* ServerKeyExchange is needed. Prepare the message. */ - ret = ssl_prepare_server_key_exchange( ssl, &signature_len ); - } - - if( ret != 0 ) - { - /* If we're starting to write a new message, set ssl->out_msglen - * to 0. But if we're resuming after an asynchronous message, - * out_msglen is the amount of data written so far and mst be - * preserved. */ - if( ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS ) - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server key exchange (pending)" ) ); - else - ssl->out_msglen = 0; - return( ret ); - } - - /* If there is a signature, write its length. - * ssl_prepare_server_key_exchange already wrote the signature - * itself at its proper place in the output buffer. */ -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) - if( signature_len != 0 ) - { - ssl->out_msg[ssl->out_msglen++] = (unsigned char)( signature_len >> 8 ); - ssl->out_msg[ssl->out_msglen++] = (unsigned char)( signature_len ); - - MBEDTLS_SSL_DEBUG_BUF( 3, "my signature", - ssl->out_msg + ssl->out_msglen, - signature_len ); - - /* Skip over the already-written signature */ - ssl->out_msglen += signature_len; - } -#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ - - /* Add header and send. */ - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE; - - ssl->state++; - - if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); - return( ret ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server key exchange" ) ); - return( 0 ); -} - -static int ssl_write_server_hello_done( mbedtls_ssl_context *ssl ) -{ - int ret; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server hello done" ) ); - - ssl->out_msglen = 4; - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_HELLO_DONE; - - ssl->state++; - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - mbedtls_ssl_send_flight_completed( ssl ); -#endif - - if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); - return( ret ); - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret ); - return( ret ); - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server hello done" ) ); - - return( 0 ); -} - -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) -static int ssl_parse_client_dh_public( mbedtls_ssl_context *ssl, unsigned char **p, - const unsigned char *end ) -{ - int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - size_t n; - - /* - * Receive G^Y mod P, premaster = (G^Y)^X mod P - */ - if( *p + 2 > end ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); - } - - n = ( (*p)[0] << 8 ) | (*p)[1]; - *p += 2; - - if( *p + n > end ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); - } - - if( ( ret = mbedtls_dhm_read_public( &ssl->handshake->dhm_ctx, *p, n ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_read_public", ret ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP ); - } - - *p += n; - - MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->handshake->dhm_ctx.GY ); - - return( ret ); -} -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) -static int ssl_resume_decrypt_pms( mbedtls_ssl_context *ssl, - unsigned char *peer_pms, - size_t *peer_pmslen, - size_t peer_pmssize ) -{ - int ret = ssl->conf->f_async_resume( ssl, - peer_pms, peer_pmslen, peer_pmssize ); - if( ret != MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS ) - { - ssl->handshake->async_in_progress = 0; - mbedtls_ssl_set_async_operation_data( ssl, NULL ); - } - MBEDTLS_SSL_DEBUG_RET( 2, "ssl_decrypt_encrypted_pms", ret ); - return( ret ); -} -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - -static int ssl_decrypt_encrypted_pms( mbedtls_ssl_context *ssl, - const unsigned char *p, - const unsigned char *end, - unsigned char *peer_pms, - size_t *peer_pmslen, - size_t peer_pmssize ) -{ - int ret; - mbedtls_pk_context *private_key = mbedtls_ssl_own_key( ssl ); - mbedtls_pk_context *public_key = &mbedtls_ssl_own_cert( ssl )->pk; - size_t len = mbedtls_pk_get_len( public_key ); - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - /* If we have already started decoding the message and there is an ongoing - * decryption operation, resume signing. */ - if( ssl->handshake->async_in_progress != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "resuming decryption operation" ) ); - return( ssl_resume_decrypt_pms( ssl, - peer_pms, peer_pmslen, peer_pmssize ) ); - } -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - - /* - * Prepare to decrypt the premaster using own private RSA key - */ -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 ) - { - if ( p + 2 > end ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); - } - if( *p++ != ( ( len >> 8 ) & 0xFF ) || - *p++ != ( ( len ) & 0xFF ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); - } - } -#endif - - if( p + len != end ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); - } - - /* - * Decrypt the premaster secret - */ -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - if( ssl->conf->f_async_decrypt_start != NULL ) - { - ret = ssl->conf->f_async_decrypt_start( ssl, - mbedtls_ssl_own_cert( ssl ), - p, len ); - switch( ret ) - { - case MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH: - /* act as if f_async_decrypt_start was null */ - break; - case 0: - ssl->handshake->async_in_progress = 1; - return( ssl_resume_decrypt_pms( ssl, - peer_pms, - peer_pmslen, - peer_pmssize ) ); - case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS: - ssl->handshake->async_in_progress = 1; - return( MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS ); - default: - MBEDTLS_SSL_DEBUG_RET( 1, "f_async_decrypt_start", ret ); - return( ret ); - } - } -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - - if( ! mbedtls_pk_can_do( private_key, MBEDTLS_PK_RSA ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no RSA private key" ) ); - return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED ); - } - - ret = mbedtls_pk_decrypt( private_key, p, len, - peer_pms, peer_pmslen, peer_pmssize, - ssl->conf->f_rng, ssl->conf->p_rng ); - return( ret ); -} - -static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl, - const unsigned char *p, - const unsigned char *end, - size_t pms_offset ) -{ - int ret; - unsigned char *pms = ssl->handshake->premaster + pms_offset; - unsigned char ver[2]; - unsigned char fake_pms[48], peer_pms[48]; - unsigned char mask; - size_t i, peer_pmslen; - unsigned int diff; - - /* In case of a failure in decryption, the decryption may write less than - * 2 bytes of output, but we always read the first two bytes. It doesn't - * matter in the end because diff will be nonzero in that case due to - * peer_pmslen being less than 48, and we only care whether diff is 0. - * But do initialize peer_pms for robustness anyway. This also makes - * memory analyzers happy (don't access uninitialized memory, even - * if it's an unsigned char). */ - peer_pms[0] = peer_pms[1] = ~0; - - ret = ssl_decrypt_encrypted_pms( ssl, p, end, - peer_pms, - &peer_pmslen, - sizeof( peer_pms ) ); - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - if ( ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS ) - return( ret ); -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - - mbedtls_ssl_write_version( ssl->handshake->max_major_ver, - ssl->handshake->max_minor_ver, - ssl->conf->transport, ver ); - - /* Avoid data-dependent branches while checking for invalid - * padding, to protect against timing-based Bleichenbacher-type - * attacks. */ - diff = (unsigned int) ret; - diff |= peer_pmslen ^ 48; - diff |= peer_pms[0] ^ ver[0]; - diff |= peer_pms[1] ^ ver[1]; - - /* mask = diff ? 0xff : 0x00 using bit operations to avoid branches */ - /* MSVC has a warning about unary minus on unsigned, but this is - * well-defined and precisely what we want to do here */ -#if defined(_MSC_VER) -#pragma warning( push ) -#pragma warning( disable : 4146 ) -#endif - mask = - ( ( diff | - diff ) >> ( sizeof( unsigned int ) * 8 - 1 ) ); -#if defined(_MSC_VER) -#pragma warning( pop ) -#endif - - /* - * Protection against Bleichenbacher's attack: invalid PKCS#1 v1.5 padding - * must not cause the connection to end immediately; instead, send a - * bad_record_mac later in the handshake. - * To protect against timing-based variants of the attack, we must - * not have any branch that depends on whether the decryption was - * successful. In particular, always generate the fake premaster secret, - * regardless of whether it will ultimately influence the output or not. - */ - ret = ssl->conf->f_rng( ssl->conf->p_rng, fake_pms, sizeof( fake_pms ) ); - if( ret != 0 ) - { - /* It's ok to abort on an RNG failure, since this does not reveal - * anything about the RSA decryption. */ - return( ret ); - } - -#if defined(MBEDTLS_SSL_DEBUG_ALL) - if( diff != 0 ) - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); -#endif - - if( sizeof( ssl->handshake->premaster ) < pms_offset || - sizeof( ssl->handshake->premaster ) - pms_offset < 48 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - ssl->handshake->pmslen = 48; - - /* Set pms to either the true or the fake PMS, without - * data-dependent branches. */ - for( i = 0; i < ssl->handshake->pmslen; i++ ) - pms[i] = ( mask & fake_pms[i] ) | ( (~mask) & peer_pms[i] ); - - return( 0 ); -} -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) -static int ssl_parse_client_psk_identity( mbedtls_ssl_context *ssl, unsigned char **p, - const unsigned char *end ) -{ - int ret = 0; - size_t n; - - if( ssl_conf_has_psk_or_cb( ssl->conf ) == 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no pre-shared key" ) ); - return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED ); - } - - /* - * Receive client pre-shared key identity name - */ - if( end - *p < 2 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); - } - - n = ( (*p)[0] << 8 ) | (*p)[1]; - *p += 2; - - if( n < 1 || n > 65535 || n > (size_t) ( end - *p ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); - } - - if( ssl->conf->f_psk != NULL ) - { - if( ssl->conf->f_psk( ssl->conf->p_psk, ssl, *p, n ) != 0 ) - ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY; - } - else - { - /* Identity is not a big secret since clients send it in the clear, - * but treat it carefully anyway, just in case */ - if( n != ssl->conf->psk_identity_len || - mbedtls_ssl_safer_memcmp( ssl->conf->psk_identity, *p, n ) != 0 ) - { - ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY; - } - } - - if( ret == MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY ) - { - MBEDTLS_SSL_DEBUG_BUF( 3, "Unknown PSK identity", *p, n ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY ); - return( MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY ); - } - - *p += n; - - return( 0 ); -} -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ - -static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl ) -{ - int ret; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info; - unsigned char *p, *end; - - ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client key exchange" ) ); - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) && \ - ( defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) ) - if( ( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA ) && - ( ssl->handshake->async_in_progress != 0 ) ) - { - /* We've already read a record and there is an asynchronous - * operation in progress to decrypt it. So skip reading the - * record. */ - MBEDTLS_SSL_DEBUG_MSG( 3, ( "will resume decryption of previously-read record" ) ); - } - else -#endif - if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); - return( ret ); - } - - p = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ); - end = ssl->in_msg + ssl->in_hslen; - - if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); - } - - if( ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); - } - -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA ) - { - if( ( ret = ssl_parse_client_dh_public( ssl, &p, end ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_dh_public" ), ret ); - return( ret ); - } - - if( p != end ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); - } - - if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx, - ssl->handshake->premaster, - MBEDTLS_PREMASTER_SIZE, - &ssl->handshake->pmslen, - ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS ); - } - - MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K ); - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA ) - { - if( ( ret = mbedtls_ecdh_read_public( &ssl->handshake->ecdh_ctx, - p, end - p) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_read_public", ret ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP ); - } - - MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, - MBEDTLS_DEBUG_ECDH_QP ); - - if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx, - &ssl->handshake->pmslen, - ssl->handshake->premaster, - MBEDTLS_MPI_MAX_SIZE, - ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS ); - } - - MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, - MBEDTLS_DEBUG_ECDH_Z ); - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ) - { - if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret ); - return( ret ); - } - - if( p != end ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); - } - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - /* For opaque PSKs, we perform the PSK-to-MS derivation atomatically - * and skip the intermediate PMS. */ - if( ssl_use_opaque_psk( ssl ) == 1 ) - MBEDTLS_SSL_DEBUG_MSG( 1, ( "skip PMS generation for opaque PSK" ) ); - else -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl, - ciphersuite_info->key_exchange ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret ); - return( ret ); - } - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) - { -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - if ( ssl->handshake->async_in_progress != 0 ) - { - /* There is an asynchronous operation in progress to - * decrypt the encrypted premaster secret, so skip - * directly to resuming this operation. */ - MBEDTLS_SSL_DEBUG_MSG( 3, ( "PSK identity already parsed" ) ); - /* Update p to skip the PSK identity. ssl_parse_encrypted_pms - * won't actually use it, but maintain p anyway for robustness. */ - p += ssl->conf->psk_identity_len + 2; - } - else -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret ); - return( ret ); - } - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - /* Opaque PSKs are currently only supported for PSK-only. */ - if( ssl_use_opaque_psk( ssl ) == 1 ) - return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); -#endif - - if( ( ret = ssl_parse_encrypted_pms( ssl, p, end, 2 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_encrypted_pms" ), ret ); - return( ret ); - } - - if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl, - ciphersuite_info->key_exchange ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret ); - return( ret ); - } - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ) - { - if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret ); - return( ret ); - } - if( ( ret = ssl_parse_client_dh_public( ssl, &p, end ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_dh_public" ), ret ); - return( ret ); - } - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - /* Opaque PSKs are currently only supported for PSK-only. */ - if( ssl_use_opaque_psk( ssl ) == 1 ) - return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); -#endif - - if( p != end ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); - } - - if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl, - ciphersuite_info->key_exchange ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret ); - return( ret ); - } - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) - { - if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret ); - return( ret ); - } - - if( ( ret = mbedtls_ecdh_read_public( &ssl->handshake->ecdh_ctx, - p, end - p ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_read_public", ret ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP ); - } - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - /* Opaque PSKs are currently only supported for PSK-only. */ - if( ssl_use_opaque_psk( ssl ) == 1 ) - return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); -#endif - - MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, - MBEDTLS_DEBUG_ECDH_QP ); - - if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl, - ciphersuite_info->key_exchange ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret ); - return( ret ); - } - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA ) - { - if( ( ret = ssl_parse_encrypted_pms( ssl, p, end, 0 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_parse_encrypted_pms_secret" ), ret ); - return( ret ); - } - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) - { - ret = mbedtls_ecjpake_read_round_two( &ssl->handshake->ecjpake_ctx, - p, end - p ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_two", ret ); - return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); - } - - ret = mbedtls_ecjpake_derive_secret( &ssl->handshake->ecjpake_ctx, - ssl->handshake->premaster, 32, &ssl->handshake->pmslen, - ssl->conf->f_rng, ssl->conf->p_rng ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_derive_secret", ret ); - return( ret ); - } - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret ); - return( ret ); - } - - ssl->state++; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse client key exchange" ) ); - - return( 0 ); -} - -#if !defined(MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED) -static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) -{ - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->transform_negotiate->ciphersuite_info; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) ); - - if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) ); - ssl->state++; - return( 0 ); - } - - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); -} -#else /* !MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */ -static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) -{ - int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - size_t i, sig_len; - unsigned char hash[48]; - unsigned char *hash_start = hash; - size_t hashlen; -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - mbedtls_pk_type_t pk_alg; -#endif - mbedtls_md_type_t md_alg; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->transform_negotiate->ciphersuite_info; - mbedtls_pk_context * peer_pk; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) ); - - if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) ); - ssl->state++; - return( 0 ); - } - -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - if( ssl->session_negotiate->peer_cert == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) ); - ssl->state++; - return( 0 ); - } -#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - if( ssl->session_negotiate->peer_cert_digest == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) ); - ssl->state++; - return( 0 ); - } -#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - - /* Read the message without adding it to the checksum */ - ret = mbedtls_ssl_read_record( ssl, 0 /* no checksum update */ ); - if( 0 != ret ) - { - MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_read_record" ), ret ); - return( ret ); - } - - ssl->state++; - - /* Process the message contents */ - if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE || - ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE_VERIFY ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); - } - - i = mbedtls_ssl_hs_hdr_len( ssl ); - -#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - peer_pk = &ssl->handshake->peer_pubkey; -#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - if( ssl->session_negotiate->peer_cert == NULL ) - { - /* Should never happen */ - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - peer_pk = &ssl->session_negotiate->peer_cert->pk; -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - - /* - * struct { - * SignatureAndHashAlgorithm algorithm; -- TLS 1.2 only - * opaque signature<0..2^16-1>; - * } DigitallySigned; - */ -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) - if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 ) - { - md_alg = MBEDTLS_MD_NONE; - hashlen = 36; - - /* For ECDSA, use SHA-1, not MD-5 + SHA-1 */ - if( mbedtls_pk_can_do( peer_pk, MBEDTLS_PK_ECDSA ) ) - { - hash_start += 16; - hashlen -= 16; - md_alg = MBEDTLS_MD_SHA1; - } - } - else -#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || - MBEDTLS_SSL_PROTO_TLS1_1 */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) - { - if( i + 2 > ssl->in_hslen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); - } - - /* - * Hash - */ - md_alg = mbedtls_ssl_md_alg_from_hash( ssl->in_msg[i] ); - - if( md_alg == MBEDTLS_MD_NONE || mbedtls_ssl_set_calc_verify_md( ssl, ssl->in_msg[i] ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "peer not adhering to requested sig_alg" - " for verify message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); - } - -#if !defined(MBEDTLS_MD_SHA1) - if( MBEDTLS_MD_SHA1 == md_alg ) - hash_start += 16; -#endif - - /* Info from md_alg will be used instead */ - hashlen = 0; - - i++; - - /* - * Signature - */ - if( ( pk_alg = mbedtls_ssl_pk_alg_from_sig( ssl->in_msg[i] ) ) - == MBEDTLS_PK_NONE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "peer not adhering to requested sig_alg" - " for verify message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); - } - - /* - * Check the certificate's key type matches the signature alg - */ - if( !mbedtls_pk_can_do( peer_pk, pk_alg ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "sig_alg doesn't match cert key" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); - } - - i++; - } - else -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - if( i + 2 > ssl->in_hslen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); - } - - sig_len = ( ssl->in_msg[i] << 8 ) | ssl->in_msg[i+1]; - i += 2; - - if( i + sig_len != ssl->in_hslen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); - } - - /* Calculate hash and verify signature */ - ssl->handshake->calc_verify( ssl, hash ); - - if( ( ret = mbedtls_pk_verify( peer_pk, - md_alg, hash_start, hashlen, - ssl->in_msg + i, sig_len ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret ); - return( ret ); - } - - mbedtls_ssl_update_handshake_status( ssl ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate verify" ) ); - - return( ret ); -} -#endif /* MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) -static int ssl_write_new_session_ticket( mbedtls_ssl_context *ssl ) -{ - int ret; - size_t tlen; - uint32_t lifetime; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write new session ticket" ) ); - - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = MBEDTLS_SSL_HS_NEW_SESSION_TICKET; - - /* - * struct { - * uint32 ticket_lifetime_hint; - * opaque ticket<0..2^16-1>; - * } NewSessionTicket; - * - * 4 . 7 ticket_lifetime_hint (0 = unspecified) - * 8 . 9 ticket_len (n) - * 10 . 9+n ticket content - */ - - if( ( ret = ssl->conf->f_ticket_write( ssl->conf->p_ticket, - ssl->session_negotiate, - ssl->out_msg + 10, - ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN, - &tlen, &lifetime ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_ticket_write", ret ); - tlen = 0; - } - - ssl->out_msg[4] = ( lifetime >> 24 ) & 0xFF; - ssl->out_msg[5] = ( lifetime >> 16 ) & 0xFF; - ssl->out_msg[6] = ( lifetime >> 8 ) & 0xFF; - ssl->out_msg[7] = ( lifetime ) & 0xFF; - - ssl->out_msg[8] = (unsigned char)( ( tlen >> 8 ) & 0xFF ); - ssl->out_msg[9] = (unsigned char)( ( tlen ) & 0xFF ); - - ssl->out_msglen = 10 + tlen; - - /* - * Morally equivalent to updating ssl->state, but NewSessionTicket and - * ChangeCipherSpec share the same state. - */ - ssl->handshake->new_session_ticket = 0; - - if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); - return( ret ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write new session ticket" ) ); - - return( 0 ); -} -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -/* - * SSL handshake -- server side -- single step - */ -int mbedtls_ssl_handshake_server_step( mbedtls_ssl_context *ssl ) -{ - int ret = 0; - - if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER || ssl->handshake == NULL ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "server state: %d", ssl->state ) ); - - if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) - return( ret ); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING ) - { - if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 ) - return( ret ); - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - switch( ssl->state ) - { - case MBEDTLS_SSL_HELLO_REQUEST: - ssl->state = MBEDTLS_SSL_CLIENT_HELLO; - break; - - /* - * <== ClientHello - */ - case MBEDTLS_SSL_CLIENT_HELLO: - ret = ssl_parse_client_hello( ssl ); - break; - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - case MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT: - return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED ); -#endif - - /* - * ==> ServerHello - * Certificate - * ( ServerKeyExchange ) - * ( CertificateRequest ) - * ServerHelloDone - */ - case MBEDTLS_SSL_SERVER_HELLO: - ret = ssl_write_server_hello( ssl ); - break; - - case MBEDTLS_SSL_SERVER_CERTIFICATE: - ret = mbedtls_ssl_write_certificate( ssl ); - break; - - case MBEDTLS_SSL_SERVER_KEY_EXCHANGE: - ret = ssl_write_server_key_exchange( ssl ); - break; - - case MBEDTLS_SSL_CERTIFICATE_REQUEST: - ret = ssl_write_certificate_request( ssl ); - break; - - case MBEDTLS_SSL_SERVER_HELLO_DONE: - ret = ssl_write_server_hello_done( ssl ); - break; - - /* - * <== ( Certificate/Alert ) - * ClientKeyExchange - * ( CertificateVerify ) - * ChangeCipherSpec - * Finished - */ - case MBEDTLS_SSL_CLIENT_CERTIFICATE: - ret = mbedtls_ssl_parse_certificate( ssl ); - break; - - case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE: - ret = ssl_parse_client_key_exchange( ssl ); - break; - - case MBEDTLS_SSL_CERTIFICATE_VERIFY: - ret = ssl_parse_certificate_verify( ssl ); - break; - - case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC: - ret = mbedtls_ssl_parse_change_cipher_spec( ssl ); - break; - - case MBEDTLS_SSL_CLIENT_FINISHED: - ret = mbedtls_ssl_parse_finished( ssl ); - break; - - /* - * ==> ( NewSessionTicket ) - * ChangeCipherSpec - * Finished - */ - case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC: -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - if( ssl->handshake->new_session_ticket != 0 ) - ret = ssl_write_new_session_ticket( ssl ); - else -#endif - ret = mbedtls_ssl_write_change_cipher_spec( ssl ); - break; - - case MBEDTLS_SSL_SERVER_FINISHED: - ret = mbedtls_ssl_write_finished( ssl ); - break; - - case MBEDTLS_SSL_FLUSH_BUFFERS: - MBEDTLS_SSL_DEBUG_MSG( 2, ( "handshake: done" ) ); - ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP; - break; - - case MBEDTLS_SSL_HANDSHAKE_WRAPUP: - mbedtls_ssl_handshake_wrapup( ssl ); - break; - - default: - MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) ); - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - return( ret ); -} -#endif /* MBEDTLS_SSL_SRV_C */ diff --git a/library/ssl_ticket.c b/library/ssl_ticket.c deleted file mode 100644 index ed65bcd63..000000000 --- a/library/ssl_ticket.c +++ /dev/null @@ -1,595 +0,0 @@ -/* - * TLS server tickets callbacks implementation - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_SSL_TICKET_C) - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#include "mbedtls/ssl_ticket.h" -#include "mbedtls/platform_util.h" - -#include - -/* - * Initialze 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 32 /* 256 bits */ - -#define TICKET_KEY_NAME_BYTES 4 -#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 - */ -static int ssl_ticket_gen_key( mbedtls_ssl_ticket_context *ctx, - unsigned char index ) -{ - int ret; - unsigned char buf[MAX_KEY_BYTES]; - mbedtls_ssl_ticket_key *key = ctx->keys + index; - -#if defined(MBEDTLS_HAVE_TIME) - key->generation_time = (uint32_t) mbedtls_time( NULL ); -#endif - - if( ( ret = ctx->f_rng( ctx->p_rng, key->name, sizeof( key->name ) ) ) != 0 ) - return( ret ); - - if( ( ret = ctx->f_rng( ctx->p_rng, buf, sizeof( buf ) ) ) != 0 ) - return( ret ); - - /* With GCM and CCM, same context can encrypt & decrypt */ - ret = mbedtls_cipher_setkey( &key->ctx, buf, - mbedtls_cipher_get_key_bitlen( &key->ctx ), - MBEDTLS_ENCRYPT ); - - mbedtls_platform_zeroize( buf, sizeof( buf ) ); - - return( ret ); -} - -/* - * Rotate/generate keys if necessary - */ -static int ssl_ticket_update_keys( mbedtls_ssl_ticket_context *ctx ) -{ -#if !defined(MBEDTLS_HAVE_TIME) - ((void) ctx); -#else - if( ctx->ticket_lifetime != 0 ) - { - uint32_t current_time = (uint32_t) mbedtls_time( NULL ); - uint32_t key_time = ctx->keys[ctx->active].generation_time; - - if( current_time >= key_time && - current_time - key_time < ctx->ticket_lifetime ) - { - return( 0 ); - } - - ctx->active = 1 - ctx->active; - - return( ssl_ticket_gen_key( ctx, ctx->active ) ); - } - else -#endif /* MBEDTLS_HAVE_TIME */ - return( 0 ); -} - -/* - * Setup context for actual use - */ -int mbedtls_ssl_ticket_setup( mbedtls_ssl_ticket_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - mbedtls_cipher_type_t cipher, - uint32_t lifetime ) -{ - int ret; - const mbedtls_cipher_info_t *cipher_info; - - ctx->f_rng = f_rng; - ctx->p_rng = p_rng; - - ctx->ticket_lifetime = lifetime; - - cipher_info = mbedtls_cipher_info_from_type( cipher); - if( cipher_info == NULL ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - if( cipher_info->mode != MBEDTLS_MODE_GCM && - cipher_info->mode != MBEDTLS_MODE_CCM ) - { - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - if( cipher_info->key_bitlen > 8 * MAX_KEY_BYTES ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - ret = mbedtls_cipher_setup_psa( &ctx->keys[0].ctx, - cipher_info, TICKET_AUTH_TAG_BYTES ); - if( ret != 0 && ret != MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ) - return( ret ); - /* We don't yet expect to support all ciphers through PSA, - * so allow fallback to ordinary mbedtls_cipher_setup(). */ - if( ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ) -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - if( ( ret = mbedtls_cipher_setup( &ctx->keys[0].ctx, cipher_info ) ) != 0 ) - return( ret ); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - ret = mbedtls_cipher_setup_psa( &ctx->keys[1].ctx, - cipher_info, TICKET_AUTH_TAG_BYTES ); - if( ret != 0 && ret != MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ) - return( ret ); - if( ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ) -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - if( ( ret = mbedtls_cipher_setup( &ctx->keys[1].ctx, cipher_info ) ) != 0 ) - return( ret ); - - if( ( ret = ssl_ticket_gen_key( ctx, 0 ) ) != 0 || - ( ret = ssl_ticket_gen_key( ctx, 1 ) ) != 0 ) - { - return( ret ); - } - - return( 0 ); -} - -/* - * Serialize a session in the following format: - * - * - If MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is enabled: - * 0 . n-1 session structure, n = sizeof(mbedtls_ssl_session) - * n . n+2 peer_cert length = m (0 if no certificate) - * n+3 . n+2+m peer cert ASN.1 - * - * - If MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is disabled: - * 0 . n-1 session structure, n = sizeof(mbedtls_ssl_session) - * n . n length of peer certificate digest = k (0 if no digest) - * n+1 . n+k peer certificate digest (digest type encoded in session) - */ -static int ssl_save_session( const mbedtls_ssl_session *session, - unsigned char *buf, size_t buf_len, - size_t *olen ) -{ - unsigned char *p = buf; - size_t left = buf_len; -#if defined(MBEDTLS_X509_CRT_PARSE_C) -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - size_t cert_len; -#else - size_t cert_digest_len; -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - - if( left < sizeof( mbedtls_ssl_session ) ) - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); - - /* This also copies the values of pointer fields in the - * session to be serialized, but they'll be ignored when - * loading the session through ssl_load_session(). */ - memcpy( p, session, sizeof( mbedtls_ssl_session ) ); - p += sizeof( mbedtls_ssl_session ); - left -= sizeof( mbedtls_ssl_session ); - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - if( session->peer_cert == NULL ) - cert_len = 0; - else - cert_len = session->peer_cert->raw.len; - - if( left < 3 + cert_len ) - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); - - *p++ = (unsigned char)( ( cert_len >> 16 ) & 0xFF ); - *p++ = (unsigned char)( ( cert_len >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( cert_len ) & 0xFF ); - left -= 3; - - if( session->peer_cert != NULL ) - memcpy( p, session->peer_cert->raw.p, cert_len ); - - p += cert_len; - left -= cert_len; -#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - if( session->peer_cert_digest != NULL ) - cert_digest_len = 0; - else - cert_digest_len = session->peer_cert_digest_len; - - if( left < 1 + cert_digest_len ) - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); - - *p++ = (unsigned char) cert_digest_len; - left--; - - if( session->peer_cert_digest != NULL ) - memcpy( p, session->peer_cert_digest, cert_digest_len ); - - p += cert_digest_len; - left -= cert_digest_len; -#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - - *olen = p - buf; - - return( 0 ); -} - -/* - * Unserialise session, see ssl_save_session() - */ -static int ssl_load_session( mbedtls_ssl_session *session, - const unsigned char *buf, size_t len ) -{ - const unsigned char *p = buf; - const unsigned char * const end = buf + len; -#if defined(MBEDTLS_X509_CRT_PARSE_C) -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - size_t cert_len; -#else - size_t cert_digest_len; -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - - if( sizeof( mbedtls_ssl_session ) > (size_t)( end - p ) ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - memcpy( session, p, sizeof( mbedtls_ssl_session ) ); - p += sizeof( mbedtls_ssl_session ); - - /* Non-NULL pointer fields of `session` are meaningless - * and potentially harmful. Zeroize them for safety. */ -#if defined(MBEDTLS_X509_CRT_PARSE_C) -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - session->peer_cert = NULL; -#else - session->peer_cert_digest = NULL; -#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ -#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) - session->ticket = NULL; -#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */ - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - /* Deserialize CRT from the end of the ticket. */ - if( 3 > (size_t)( end - p ) ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - cert_len = ( p[0] << 16 ) | ( p[1] << 8 ) | p[2]; - p += 3; - - if( cert_len != 0 ) - { - int ret; - - if( cert_len > (size_t)( end - p ) ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - session->peer_cert = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) ); - - if( session->peer_cert == NULL ) - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - - mbedtls_x509_crt_init( session->peer_cert ); - - if( ( ret = mbedtls_x509_crt_parse_der( session->peer_cert, - p, cert_len ) ) != 0 ) - { - mbedtls_x509_crt_free( session->peer_cert ); - mbedtls_free( session->peer_cert ); - session->peer_cert = NULL; - return( ret ); - } - - p += cert_len; - } -#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - /* Deserialize CRT digest from the end of the ticket. */ - if( 1 > (size_t)( end - p ) ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - cert_digest_len = (size_t) p[0]; - p++; - - if( cert_digest_len != 0 ) - { - if( cert_digest_len > (size_t)( end - p ) || - cert_digest_len != session->peer_cert_digest_len ) - { - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - session->peer_cert_digest = mbedtls_calloc( 1, cert_digest_len ); - if( session->peer_cert_digest == NULL ) - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - - memcpy( session->peer_cert_digest, p, cert_digest_len ); - p += cert_digest_len; - } -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - - if( p != end ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - 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_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; - unsigned char *tag; - size_t clear_len, ciph_len; - - *tlen = 0; - - if( ctx == NULL || ctx->f_rng == 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. */ - if( end - start < TICKET_MIN_LEN ) - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); - -#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 = ctx->ticket_lifetime; - - memcpy( key_name, key->name, TICKET_KEY_NAME_BYTES ); - - if( ( ret = ctx->f_rng( ctx->p_rng, iv, TICKET_IV_BYTES ) ) != 0 ) - goto cleanup; - - /* Dump session state */ - if( ( ret = ssl_save_session( session, - state, end - state, &clear_len ) ) != 0 || - (unsigned long) clear_len > 65535 ) - { - goto cleanup; - } - state_len_bytes[0] = ( clear_len >> 8 ) & 0xff; - state_len_bytes[1] = ( clear_len ) & 0xff; - - /* Encrypt and authenticate */ - tag = state + clear_len; - if( ( ret = mbedtls_cipher_auth_encrypt( &key->ctx, - iv, TICKET_IV_BYTES, - /* Additional data: key name, IV and length */ - key_name, TICKET_ADD_DATA_LEN, - state, clear_len, state, &ciph_len, - tag, TICKET_AUTH_TAG_BYTES ) ) != 0 ) - { - goto cleanup; - } - if( ciph_len != clear_len ) - { - ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; - goto cleanup; - } - - *tlen = TICKET_MIN_LEN + ciph_len; - -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_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; - unsigned char *tag; - size_t enc_len, clear_len; - - if( ctx == NULL || ctx->f_rng == 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 = ( enc_len_p[0] << 8 ) | enc_len_p[1]; - tag = ticket + enc_len; - - 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( ( ret = mbedtls_cipher_auth_decrypt( &key->ctx, - iv, TICKET_IV_BYTES, - /* Additional data: key name, IV and length */ - key_name, TICKET_ADD_DATA_LEN, - ticket, enc_len, - ticket, &clear_len, - tag, TICKET_AUTH_TAG_BYTES ) ) != 0 ) - { - if( ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED ) - ret = MBEDTLS_ERR_SSL_INVALID_MAC; - - goto cleanup; - } - if( clear_len != enc_len ) - { - ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; - goto cleanup; - } - - /* Actually load session */ - if( ( ret = ssl_load_session( session, ticket, clear_len ) ) != 0 ) - goto cleanup; - -#if defined(MBEDTLS_HAVE_TIME) - { - /* Check for expiration */ - mbedtls_time_t current_time = mbedtls_time( NULL ); - - if( current_time < session->start || - (uint32_t)( current_time - session->start ) > ctx->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 ) -{ - mbedtls_cipher_free( &ctx->keys[0].ctx ); - mbedtls_cipher_free( &ctx->keys[1].ctx ); - -#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 */ diff --git a/library/ssl_tls.c b/library/ssl_tls.c deleted file mode 100644 index abe2450eb..000000000 --- a/library/ssl_tls.c +++ /dev/null @@ -1,10634 +0,0 @@ -/* - * SSLv3/TLSv1 shared functions - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -/* - * The SSL 3.0 specification was drafted by Netscape in 1996, - * and became an IETF standard in 1999. - * - * http://wp.netscape.com/eng/ssl3/ - * http://www.ietf.org/rfc/rfc2246.txt - * http://www.ietf.org/rfc/rfc4346.txt - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_SSL_TLS_C) - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#include "mbedtls/debug.h" -#include "mbedtls/ssl.h" -#include "mbedtls/ssl_internal.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "mbedtls/psa_util.h" -#include "psa/crypto.h" -#endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -#include "mbedtls/oid.h" -#endif - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "mbedtls/psa_util.h" -#endif - -static void ssl_reset_in_out_pointers( mbedtls_ssl_context *ssl ); -static uint32_t ssl_get_hs_total_len( mbedtls_ssl_context const *ssl ); - -/* Length of the "epoch" field in the record header */ -static inline size_t ssl_ep_len( const mbedtls_ssl_context *ssl ) -{ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - return( 2 ); -#else - ((void) ssl); -#endif - return( 0 ); -} - -/* - * Start a timer. - * Passing millisecs = 0 cancels a running timer. - */ -static void ssl_set_timer( mbedtls_ssl_context *ssl, uint32_t millisecs ) -{ - if( ssl->f_set_timer == NULL ) - return; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "set_timer to %d ms", (int) millisecs ) ); - ssl->f_set_timer( ssl->p_timer, millisecs / 4, millisecs ); -} - -/* - * Return -1 is timer is expired, 0 if it isn't. - */ -static int ssl_check_timer( mbedtls_ssl_context *ssl ) -{ - if( ssl->f_get_timer == NULL ) - return( 0 ); - - if( ssl->f_get_timer( ssl->p_timer ) == 2 ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "timer expired" ) ); - return( -1 ); - } - - return( 0 ); -} - -static void ssl_update_out_pointers( mbedtls_ssl_context *ssl, - mbedtls_ssl_transform *transform ); -static void ssl_update_in_pointers( mbedtls_ssl_context *ssl, - mbedtls_ssl_transform *transform ); - -#define SSL_DONT_FORCE_FLUSH 0 -#define SSL_FORCE_FLUSH 1 - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - -/* Forward declarations for functions related to message buffering. */ -static void ssl_buffering_free( mbedtls_ssl_context *ssl ); -static void ssl_buffering_free_slot( mbedtls_ssl_context *ssl, - uint8_t slot ); -static void ssl_free_buffered_record( mbedtls_ssl_context *ssl ); -static int ssl_load_buffered_message( mbedtls_ssl_context *ssl ); -static int ssl_load_buffered_record( mbedtls_ssl_context *ssl ); -static int ssl_buffer_message( mbedtls_ssl_context *ssl ); -static int ssl_buffer_future_record( mbedtls_ssl_context *ssl ); -static int ssl_next_record_is_in_datagram( mbedtls_ssl_context *ssl ); - -static size_t ssl_get_current_mtu( const mbedtls_ssl_context *ssl ); -static size_t ssl_get_maximum_datagram_size( mbedtls_ssl_context const *ssl ) -{ - size_t mtu = ssl_get_current_mtu( ssl ); - - if( mtu != 0 && mtu < MBEDTLS_SSL_OUT_BUFFER_LEN ) - return( mtu ); - - return( MBEDTLS_SSL_OUT_BUFFER_LEN ); -} - -static int ssl_get_remaining_space_in_datagram( mbedtls_ssl_context const *ssl ) -{ - size_t const bytes_written = ssl->out_left; - size_t const mtu = ssl_get_maximum_datagram_size( ssl ); - - /* Double-check that the write-index hasn't gone - * past what we can transmit in a single datagram. */ - if( bytes_written > mtu ) - { - /* Should never happen... */ - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - return( (int) ( mtu - bytes_written ) ); -} - -static int ssl_get_remaining_payload_in_datagram( mbedtls_ssl_context const *ssl ) -{ - int ret; - size_t remaining, expansion; - size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN; - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - const size_t mfl = mbedtls_ssl_get_max_frag_len( ssl ); - - if( max_len > mfl ) - max_len = mfl; - - /* By the standard (RFC 6066 Sect. 4), the MFL extension - * only limits the maximum record payload size, so in theory - * we would be allowed to pack multiple records of payload size - * MFL into a single datagram. However, this would mean that there's - * no way to explicitly communicate MTU restrictions to the peer. - * - * The following reduction of max_len makes sure that we never - * write datagrams larger than MFL + Record Expansion Overhead. - */ - if( max_len <= ssl->out_left ) - return( 0 ); - - max_len -= ssl->out_left; -#endif - - ret = ssl_get_remaining_space_in_datagram( ssl ); - if( ret < 0 ) - return( ret ); - remaining = (size_t) ret; - - ret = mbedtls_ssl_get_record_expansion( ssl ); - if( ret < 0 ) - return( ret ); - expansion = (size_t) ret; - - if( remaining <= expansion ) - return( 0 ); - - remaining -= expansion; - if( remaining >= max_len ) - remaining = max_len; - - return( (int) remaining ); -} - -/* - * Double the retransmit timeout value, within the allowed range, - * returning -1 if the maximum value has already been reached. - */ -static int ssl_double_retransmit_timeout( mbedtls_ssl_context *ssl ) -{ - uint32_t new_timeout; - - if( ssl->handshake->retransmit_timeout >= ssl->conf->hs_timeout_max ) - return( -1 ); - - /* Implement the final paragraph of RFC 6347 section 4.1.1.1 - * in the following way: after the initial transmission and a first - * retransmission, back off to a temporary estimated MTU of 508 bytes. - * This value is guaranteed to be deliverable (if not guaranteed to be - * delivered) of any compliant IPv4 (and IPv6) network, and should work - * on most non-IP stacks too. */ - if( ssl->handshake->retransmit_timeout != ssl->conf->hs_timeout_min ) - { - ssl->handshake->mtu = 508; - MBEDTLS_SSL_DEBUG_MSG( 2, ( "mtu autoreduction to %d bytes", ssl->handshake->mtu ) ); - } - - new_timeout = 2 * ssl->handshake->retransmit_timeout; - - /* Avoid arithmetic overflow and range overflow */ - if( new_timeout < ssl->handshake->retransmit_timeout || - new_timeout > ssl->conf->hs_timeout_max ) - { - new_timeout = ssl->conf->hs_timeout_max; - } - - ssl->handshake->retransmit_timeout = new_timeout; - MBEDTLS_SSL_DEBUG_MSG( 3, ( "update timeout value to %d millisecs", - ssl->handshake->retransmit_timeout ) ); - - return( 0 ); -} - -static void ssl_reset_retransmit_timeout( mbedtls_ssl_context *ssl ) -{ - ssl->handshake->retransmit_timeout = ssl->conf->hs_timeout_min; - MBEDTLS_SSL_DEBUG_MSG( 3, ( "update timeout value to %d millisecs", - ssl->handshake->retransmit_timeout ) ); -} -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) -/* - * Convert max_fragment_length codes to length. - * RFC 6066 says: - * enum{ - * 2^9(1), 2^10(2), 2^11(3), 2^12(4), (255) - * } MaxFragmentLength; - * and we add 0 -> extension unused - */ -static unsigned int ssl_mfl_code_to_length( int mfl ) -{ - switch( mfl ) - { - case MBEDTLS_SSL_MAX_FRAG_LEN_NONE: - return ( MBEDTLS_TLS_EXT_ADV_CONTENT_LEN ); - case MBEDTLS_SSL_MAX_FRAG_LEN_512: - return 512; - case MBEDTLS_SSL_MAX_FRAG_LEN_1024: - return 1024; - case MBEDTLS_SSL_MAX_FRAG_LEN_2048: - return 2048; - case MBEDTLS_SSL_MAX_FRAG_LEN_4096: - return 4096; - default: - return ( MBEDTLS_TLS_EXT_ADV_CONTENT_LEN ); - } -} -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -int mbedtls_ssl_session_copy( mbedtls_ssl_session *dst, - const mbedtls_ssl_session *src ) -{ - mbedtls_ssl_session_free( dst ); - memcpy( dst, src, sizeof( mbedtls_ssl_session ) ); - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - if( src->peer_cert != NULL ) - { - int ret; - - dst->peer_cert = mbedtls_calloc( 1, sizeof(mbedtls_x509_crt) ); - if( dst->peer_cert == NULL ) - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - - mbedtls_x509_crt_init( dst->peer_cert ); - - if( ( ret = mbedtls_x509_crt_parse_der( dst->peer_cert, src->peer_cert->raw.p, - src->peer_cert->raw.len ) ) != 0 ) - { - mbedtls_free( dst->peer_cert ); - dst->peer_cert = NULL; - return( ret ); - } - } -#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - if( src->peer_cert_digest != NULL ) - { - dst->peer_cert_digest = - mbedtls_calloc( 1, src->peer_cert_digest_len ); - if( dst->peer_cert_digest == NULL ) - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - - memcpy( dst->peer_cert_digest, src->peer_cert_digest, - src->peer_cert_digest_len ); - dst->peer_cert_digest_type = src->peer_cert_digest_type; - dst->peer_cert_digest_len = src->peer_cert_digest_len; - } -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) - if( src->ticket != NULL ) - { - dst->ticket = mbedtls_calloc( 1, src->ticket_len ); - if( dst->ticket == NULL ) - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - - memcpy( dst->ticket, src->ticket, src->ticket_len ); - } -#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */ - - return( 0 ); -} - -#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) -int (*mbedtls_ssl_hw_record_init)( mbedtls_ssl_context *ssl, - const unsigned char *key_enc, const unsigned char *key_dec, - size_t keylen, - const unsigned char *iv_enc, const unsigned char *iv_dec, - size_t ivlen, - const unsigned char *mac_enc, const unsigned char *mac_dec, - size_t maclen ) = NULL; -int (*mbedtls_ssl_hw_record_activate)( mbedtls_ssl_context *ssl, int direction) = NULL; -int (*mbedtls_ssl_hw_record_reset)( mbedtls_ssl_context *ssl ) = NULL; -int (*mbedtls_ssl_hw_record_write)( mbedtls_ssl_context *ssl ) = NULL; -int (*mbedtls_ssl_hw_record_read)( mbedtls_ssl_context *ssl ) = NULL; -int (*mbedtls_ssl_hw_record_finish)( mbedtls_ssl_context *ssl ) = NULL; -#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ - -/* - * Key material generation - */ -#if defined(MBEDTLS_SSL_PROTO_SSL3) -static int ssl3_prf( const unsigned char *secret, size_t slen, - const char *label, - const unsigned char *random, size_t rlen, - unsigned char *dstbuf, size_t dlen ) -{ - int ret = 0; - size_t i; - mbedtls_md5_context md5; - mbedtls_sha1_context sha1; - unsigned char padding[16]; - unsigned char sha1sum[20]; - ((void)label); - - mbedtls_md5_init( &md5 ); - mbedtls_sha1_init( &sha1 ); - - /* - * SSLv3: - * block = - * MD5( secret + SHA1( 'A' + secret + random ) ) + - * MD5( secret + SHA1( 'BB' + secret + random ) ) + - * MD5( secret + SHA1( 'CCC' + secret + random ) ) + - * ... - */ - for( i = 0; i < dlen / 16; i++ ) - { - memset( padding, (unsigned char) ('A' + i), 1 + i ); - - if( ( ret = mbedtls_sha1_starts_ret( &sha1 ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_sha1_update_ret( &sha1, padding, 1 + i ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_sha1_update_ret( &sha1, secret, slen ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_sha1_update_ret( &sha1, random, rlen ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_sha1_finish_ret( &sha1, sha1sum ) ) != 0 ) - goto exit; - - if( ( ret = mbedtls_md5_starts_ret( &md5 ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md5_update_ret( &md5, secret, slen ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md5_update_ret( &md5, sha1sum, 20 ) ) != 0 ) - goto exit; - if( ( ret = mbedtls_md5_finish_ret( &md5, dstbuf + i * 16 ) ) != 0 ) - goto exit; - } - -exit: - mbedtls_md5_free( &md5 ); - mbedtls_sha1_free( &sha1 ); - - mbedtls_platform_zeroize( padding, sizeof( padding ) ); - mbedtls_platform_zeroize( sha1sum, sizeof( sha1sum ) ); - - return( ret ); -} -#endif /* MBEDTLS_SSL_PROTO_SSL3 */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) -static int tls1_prf( const unsigned char *secret, size_t slen, - const char *label, - const unsigned char *random, size_t rlen, - unsigned char *dstbuf, size_t dlen ) -{ - size_t nb, hs; - size_t i, j, k; - const unsigned char *S1, *S2; - unsigned char tmp[128]; - unsigned char h_i[20]; - const mbedtls_md_info_t *md_info; - mbedtls_md_context_t md_ctx; - int ret; - - mbedtls_md_init( &md_ctx ); - - if( sizeof( tmp ) < 20 + strlen( label ) + rlen ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - hs = ( slen + 1 ) / 2; - S1 = secret; - S2 = secret + slen - hs; - - nb = strlen( label ); - memcpy( tmp + 20, label, nb ); - memcpy( tmp + 20 + nb, random, rlen ); - nb += rlen; - - /* - * First compute P_md5(secret,label+random)[0..dlen] - */ - if( ( md_info = mbedtls_md_info_from_type( MBEDTLS_MD_MD5 ) ) == NULL ) - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - - if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 ) - return( ret ); - - mbedtls_md_hmac_starts( &md_ctx, S1, hs ); - mbedtls_md_hmac_update( &md_ctx, tmp + 20, nb ); - mbedtls_md_hmac_finish( &md_ctx, 4 + tmp ); - - for( i = 0; i < dlen; i += 16 ) - { - mbedtls_md_hmac_reset ( &md_ctx ); - mbedtls_md_hmac_update( &md_ctx, 4 + tmp, 16 + nb ); - mbedtls_md_hmac_finish( &md_ctx, h_i ); - - mbedtls_md_hmac_reset ( &md_ctx ); - mbedtls_md_hmac_update( &md_ctx, 4 + tmp, 16 ); - mbedtls_md_hmac_finish( &md_ctx, 4 + tmp ); - - k = ( i + 16 > dlen ) ? dlen % 16 : 16; - - for( j = 0; j < k; j++ ) - dstbuf[i + j] = h_i[j]; - } - - mbedtls_md_free( &md_ctx ); - - /* - * XOR out with P_sha1(secret,label+random)[0..dlen] - */ - if( ( md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ) ) == NULL ) - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - - if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 ) - return( ret ); - - mbedtls_md_hmac_starts( &md_ctx, S2, hs ); - mbedtls_md_hmac_update( &md_ctx, tmp + 20, nb ); - mbedtls_md_hmac_finish( &md_ctx, tmp ); - - for( i = 0; i < dlen; i += 20 ) - { - mbedtls_md_hmac_reset ( &md_ctx ); - mbedtls_md_hmac_update( &md_ctx, tmp, 20 + nb ); - mbedtls_md_hmac_finish( &md_ctx, h_i ); - - mbedtls_md_hmac_reset ( &md_ctx ); - mbedtls_md_hmac_update( &md_ctx, tmp, 20 ); - mbedtls_md_hmac_finish( &md_ctx, tmp ); - - k = ( i + 20 > dlen ) ? dlen % 20 : 20; - - for( j = 0; j < k; j++ ) - dstbuf[i + j] = (unsigned char)( dstbuf[i + j] ^ h_i[j] ); - } - - mbedtls_md_free( &md_ctx ); - - mbedtls_platform_zeroize( tmp, sizeof( tmp ) ); - mbedtls_platform_zeroize( h_i, sizeof( h_i ) ); - - return( 0 ); -} -#endif /* MBEDTLS_SSL_PROTO_TLS1) || MBEDTLS_SSL_PROTO_TLS1_1 */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_USE_PSA_CRYPTO) -static int tls_prf_generic( mbedtls_md_type_t md_type, - const unsigned char *secret, size_t slen, - const char *label, - const unsigned char *random, size_t rlen, - unsigned char *dstbuf, size_t dlen ) -{ - psa_status_t status; - psa_algorithm_t alg; - psa_key_policy_t policy; - psa_key_handle_t master_slot; - psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT; - - if( ( status = psa_allocate_key( &master_slot ) ) != PSA_SUCCESS ) - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - - if( md_type == MBEDTLS_MD_SHA384 ) - alg = PSA_ALG_TLS12_PRF(PSA_ALG_SHA_384); - else - alg = PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256); - - policy = psa_key_policy_init(); - psa_key_policy_set_usage( &policy, - PSA_KEY_USAGE_DERIVE, - alg ); - status = psa_set_key_policy( master_slot, &policy ); - if( status != PSA_SUCCESS ) - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - - status = psa_import_key( master_slot, PSA_KEY_TYPE_DERIVE, secret, slen ); - if( status != PSA_SUCCESS ) - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - - status = psa_key_derivation( &generator, - master_slot, alg, - random, rlen, - (unsigned char const *) label, - (size_t) strlen( label ), - dlen ); - if( status != PSA_SUCCESS ) - { - psa_generator_abort( &generator ); - psa_destroy_key( master_slot ); - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - } - - status = psa_generator_read( &generator, dstbuf, dlen ); - if( status != PSA_SUCCESS ) - { - psa_generator_abort( &generator ); - psa_destroy_key( master_slot ); - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - } - - status = psa_generator_abort( &generator ); - if( status != PSA_SUCCESS ) - { - psa_destroy_key( master_slot ); - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - } - - status = psa_destroy_key( master_slot ); - if( status != PSA_SUCCESS ) - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - - return( 0 ); -} - -#else /* MBEDTLS_USE_PSA_CRYPTO */ - -static int tls_prf_generic( mbedtls_md_type_t md_type, - const unsigned char *secret, size_t slen, - const char *label, - const unsigned char *random, size_t rlen, - unsigned char *dstbuf, size_t dlen ) -{ - size_t nb; - size_t i, j, k, md_len; - unsigned char tmp[128]; - unsigned char h_i[MBEDTLS_MD_MAX_SIZE]; - const mbedtls_md_info_t *md_info; - mbedtls_md_context_t md_ctx; - int ret; - - mbedtls_md_init( &md_ctx ); - - if( ( md_info = mbedtls_md_info_from_type( md_type ) ) == NULL ) - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - - md_len = mbedtls_md_get_size( md_info ); - - if( sizeof( tmp ) < md_len + strlen( label ) + rlen ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - nb = strlen( label ); - memcpy( tmp + md_len, label, nb ); - memcpy( tmp + md_len + nb, random, rlen ); - nb += rlen; - - /* - * Compute P_(secret, label + random)[0..dlen] - */ - if ( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 ) - return( ret ); - - mbedtls_md_hmac_starts( &md_ctx, secret, slen ); - mbedtls_md_hmac_update( &md_ctx, tmp + md_len, nb ); - mbedtls_md_hmac_finish( &md_ctx, tmp ); - - for( i = 0; i < dlen; i += md_len ) - { - mbedtls_md_hmac_reset ( &md_ctx ); - mbedtls_md_hmac_update( &md_ctx, tmp, md_len + nb ); - mbedtls_md_hmac_finish( &md_ctx, h_i ); - - mbedtls_md_hmac_reset ( &md_ctx ); - mbedtls_md_hmac_update( &md_ctx, tmp, md_len ); - mbedtls_md_hmac_finish( &md_ctx, tmp ); - - k = ( i + md_len > dlen ) ? dlen % md_len : md_len; - - for( j = 0; j < k; j++ ) - dstbuf[i + j] = h_i[j]; - } - - mbedtls_md_free( &md_ctx ); - - mbedtls_platform_zeroize( tmp, sizeof( tmp ) ); - mbedtls_platform_zeroize( h_i, sizeof( h_i ) ); - - return( 0 ); -} -#endif /* MBEDTLS_USE_PSA_CRYPTO */ -#if defined(MBEDTLS_SHA256_C) -static int tls_prf_sha256( const unsigned char *secret, size_t slen, - const char *label, - const unsigned char *random, size_t rlen, - unsigned char *dstbuf, size_t dlen ) -{ - return( tls_prf_generic( MBEDTLS_MD_SHA256, secret, slen, - label, random, rlen, dstbuf, dlen ) ); -} -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) -static int tls_prf_sha384( const unsigned char *secret, size_t slen, - const char *label, - const unsigned char *random, size_t rlen, - unsigned char *dstbuf, size_t dlen ) -{ - return( tls_prf_generic( MBEDTLS_MD_SHA384, secret, slen, - label, random, rlen, dstbuf, dlen ) ); -} -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -static void ssl_update_checksum_start( mbedtls_ssl_context *, const unsigned char *, size_t ); - -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) -static void ssl_update_checksum_md5sha1( mbedtls_ssl_context *, const unsigned char *, size_t ); -#endif - -#if defined(MBEDTLS_SSL_PROTO_SSL3) -static void ssl_calc_verify_ssl( mbedtls_ssl_context *, unsigned char * ); -static void ssl_calc_finished_ssl( mbedtls_ssl_context *, unsigned char *, int ); -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) -static void ssl_calc_verify_tls( mbedtls_ssl_context *, unsigned char * ); -static void ssl_calc_finished_tls( mbedtls_ssl_context *, unsigned char *, int ); -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_SHA256_C) -static void ssl_update_checksum_sha256( mbedtls_ssl_context *, const unsigned char *, size_t ); -static void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *,unsigned char * ); -static void ssl_calc_finished_tls_sha256( mbedtls_ssl_context *,unsigned char *, int ); -#endif - -#if defined(MBEDTLS_SHA512_C) -static void ssl_update_checksum_sha384( mbedtls_ssl_context *, const unsigned char *, size_t ); -static void ssl_calc_verify_tls_sha384( mbedtls_ssl_context *, unsigned char * ); -static void ssl_calc_finished_tls_sha384( mbedtls_ssl_context *, unsigned char *, int ); -#endif -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) && \ - defined(MBEDTLS_USE_PSA_CRYPTO) -static int ssl_use_opaque_psk( mbedtls_ssl_context const *ssl ) -{ - if( ssl->conf->f_psk != NULL ) - { - /* If we've used a callback to select the PSK, - * the static configuration is irrelevant. */ - if( ssl->handshake->psk_opaque != 0 ) - return( 1 ); - - return( 0 ); - } - - if( ssl->conf->psk_opaque != 0 ) - return( 1 ); - - return( 0 ); -} -#endif /* MBEDTLS_USE_PSA_CRYPTO && - MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ - -int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) -{ - int ret = 0; -#if defined(MBEDTLS_USE_PSA_CRYPTO) - int psa_fallthrough; -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - unsigned char tmp[64]; - unsigned char keyblk[256]; - unsigned char *key1; - unsigned char *key2; - unsigned char *mac_enc; - unsigned char *mac_dec; - size_t mac_key_len; - size_t iv_copy_len; - size_t taglen = 0; - const mbedtls_cipher_info_t *cipher_info; - const mbedtls_md_info_t *md_info; - - /* cf. RFC 5246, Section 8.1: - * "The master secret is always exactly 48 bytes in length." */ - size_t const master_secret_len = 48; - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - unsigned char session_hash[48]; -#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ - - mbedtls_ssl_session *session = ssl->session_negotiate; - mbedtls_ssl_transform *transform = ssl->transform_negotiate; - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> derive keys" ) ); - - cipher_info = mbedtls_cipher_info_from_type( transform->ciphersuite_info->cipher ); - if( cipher_info == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "cipher info for %d not found", - transform->ciphersuite_info->cipher ) ); - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - md_info = mbedtls_md_info_from_type( transform->ciphersuite_info->mac ); - if( md_info == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "mbedtls_md info for %d not found", - transform->ciphersuite_info->mac ) ); - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - /* - * Set appropriate PRF function and other SSL / TLS / TLS1.2 functions - */ -#if defined(MBEDTLS_SSL_PROTO_SSL3) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) - { - handshake->tls_prf = ssl3_prf; - handshake->calc_verify = ssl_calc_verify_ssl; - handshake->calc_finished = ssl_calc_finished_ssl; - } - else -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) - if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 ) - { - handshake->tls_prf = tls1_prf; - handshake->calc_verify = ssl_calc_verify_tls; - handshake->calc_finished = ssl_calc_finished_tls; - } - else -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_SHA512_C) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 && - transform->ciphersuite_info->mac == MBEDTLS_MD_SHA384 ) - { - handshake->tls_prf = tls_prf_sha384; - handshake->calc_verify = ssl_calc_verify_tls_sha384; - handshake->calc_finished = ssl_calc_finished_tls_sha384; - } - else -#endif -#if defined(MBEDTLS_SHA256_C) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) - { - handshake->tls_prf = tls_prf_sha256; - handshake->calc_verify = ssl_calc_verify_tls_sha256; - handshake->calc_finished = ssl_calc_finished_tls_sha256; - } - else -#endif -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - /* - * SSLv3: - * master = - * MD5( premaster + SHA1( 'A' + premaster + randbytes ) ) + - * MD5( premaster + SHA1( 'BB' + premaster + randbytes ) ) + - * MD5( premaster + SHA1( 'CCC' + premaster + randbytes ) ) - * - * TLSv1+: - * master = PRF( premaster, "master secret", randbytes )[0..47] - */ - if( handshake->resume != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "no premaster (session resumed)" ) ); - } - else - { - /* The label for the KDF used for key expansion. - * This is either "master secret" or "extended master secret" - * depending on whether the Extended Master Secret extension - * is used. */ - char const *lbl = "master secret"; - - /* The salt for the KDF used for key expansion. - * - If the Extended Master Secret extension is not used, - * this is ClientHello.Random + ServerHello.Random - * (see Sect. 8.1 in RFC 5246). - * - If the Extended Master Secret extension is used, - * this is the transcript of the handshake so far. - * (see Sect. 4 in RFC 7627). */ - unsigned char const *salt = handshake->randbytes; - size_t salt_len = 64; - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->transform_negotiate->ciphersuite_info; - mbedtls_md_type_t const md_type = ciphersuite_info->mac; -#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - if( ssl->handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "using extended master secret" ) ); - - lbl = "extended master secret"; - salt = session_hash; - ssl->handshake->calc_verify( ssl, session_hash ); -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) - { -#if defined(MBEDTLS_SHA512_C) - if( md_type == MBEDTLS_MD_SHA384 ) - salt_len = 48; - else -#endif /* MBEDTLS_SHA512_C */ - salt_len = 32; - } - else -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - salt_len = 36; - - MBEDTLS_SSL_DEBUG_BUF( 3, "session hash", session_hash, salt_len ); - } -#endif /* MBEDTLS_SSL_EXTENDED_MS_ENABLED */ - -#if defined(MBEDTLS_USE_PSA_CRYPTO) && \ - defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK && - ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 && - ssl_use_opaque_psk( ssl ) == 1 ) - { - /* Perform PSK-to-MS expansion in a single step. */ - psa_status_t status; - psa_algorithm_t alg; - psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT; - psa_key_handle_t psk; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "perform PSA-based PSK-to-MS expansion" ) ); - - psk = ssl->conf->psk_opaque; - if( ssl->handshake->psk_opaque != 0 ) - psk = ssl->handshake->psk_opaque; - - if( md_type == MBEDTLS_MD_SHA384 ) - alg = PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_384); - else - alg = PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256); - - status = psa_key_derivation( &generator, psk, alg, - salt, salt_len, - (unsigned char const *) lbl, - (size_t) strlen( lbl ), - master_secret_len ); - if( status != PSA_SUCCESS ) - { - psa_generator_abort( &generator ); - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - } - - status = psa_generator_read( &generator, session->master, - master_secret_len ); - if( status != PSA_SUCCESS ) - { - psa_generator_abort( &generator ); - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - } - - status = psa_generator_abort( &generator ); - if( status != PSA_SUCCESS ) - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - } - else -#endif - { - ret = handshake->tls_prf( handshake->premaster, handshake->pmslen, - lbl, salt, salt_len, - session->master, - master_secret_len ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret ); - return( ret ); - } - - MBEDTLS_SSL_DEBUG_BUF( 3, "premaster secret", - handshake->premaster, - handshake->pmslen ); - - mbedtls_platform_zeroize( handshake->premaster, - sizeof(handshake->premaster) ); - } - } - - /* - * Swap the client and server random values. - */ - memcpy( tmp, handshake->randbytes, 64 ); - memcpy( handshake->randbytes, tmp + 32, 32 ); - memcpy( handshake->randbytes + 32, tmp, 32 ); - mbedtls_platform_zeroize( tmp, sizeof( tmp ) ); - - /* - * SSLv3: - * key block = - * MD5( master + SHA1( 'A' + master + randbytes ) ) + - * MD5( master + SHA1( 'BB' + master + randbytes ) ) + - * MD5( master + SHA1( 'CCC' + master + randbytes ) ) + - * MD5( master + SHA1( 'DDDD' + master + randbytes ) ) + - * ... - * - * TLSv1: - * key block = PRF( master, "key expansion", randbytes ) - */ - ret = handshake->tls_prf( session->master, 48, "key expansion", - handshake->randbytes, 64, keyblk, 256 ); - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret ); - return( ret ); - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite = %s", - mbedtls_ssl_get_ciphersuite_name( session->ciphersuite ) ) ); - MBEDTLS_SSL_DEBUG_BUF( 3, "master secret", session->master, 48 ); - MBEDTLS_SSL_DEBUG_BUF( 4, "random bytes", handshake->randbytes, 64 ); - MBEDTLS_SSL_DEBUG_BUF( 4, "key block", keyblk, 256 ); - - mbedtls_platform_zeroize( handshake->randbytes, - sizeof( handshake->randbytes ) ); - - /* - * Determine the appropriate key, IV and MAC length. - */ - - transform->keylen = cipher_info->key_bitlen / 8; - - if( cipher_info->mode == MBEDTLS_MODE_GCM || - cipher_info->mode == MBEDTLS_MODE_CCM || - cipher_info->mode == MBEDTLS_MODE_CHACHAPOLY ) - { - size_t explicit_ivlen; - - transform->maclen = 0; - mac_key_len = 0; - - /* All modes haves 96-bit IVs; - * GCM and CCM has 4 implicit and 8 explicit bytes - * ChachaPoly has all 12 bytes implicit - */ - transform->ivlen = 12; - if( cipher_info->mode == MBEDTLS_MODE_CHACHAPOLY ) - transform->fixed_ivlen = 12; - else - transform->fixed_ivlen = 4; - - /* All modes have 128-bit tags, except CCM_8 (ciphersuite flag) */ - taglen = transform->ciphersuite_info->flags & - MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16; - - - /* Minimum length of encrypted record */ - explicit_ivlen = transform->ivlen - transform->fixed_ivlen; - transform->minlen = explicit_ivlen + taglen; - } - else - { - /* Initialize HMAC contexts */ - if( ( ret = mbedtls_md_setup( &transform->md_ctx_enc, md_info, 1 ) ) != 0 || - ( ret = mbedtls_md_setup( &transform->md_ctx_dec, md_info, 1 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret ); - return( ret ); - } - - /* Get MAC length */ - mac_key_len = mbedtls_md_get_size( md_info ); - transform->maclen = mac_key_len; - -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) - /* - * If HMAC is to be truncated, we shall keep the leftmost bytes, - * (rfc 6066 page 13 or rfc 2104 section 4), - * so we only need to adjust the length here. - */ - if( session->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_ENABLED ) - { - transform->maclen = MBEDTLS_SSL_TRUNCATED_HMAC_LEN; - -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT) - /* Fall back to old, non-compliant version of the truncated - * HMAC implementation which also truncates the key - * (Mbed TLS versions from 1.3 to 2.6.0) */ - mac_key_len = transform->maclen; -#endif - } -#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ - - /* IV length */ - transform->ivlen = cipher_info->iv_size; - - /* Minimum length */ - if( cipher_info->mode == MBEDTLS_MODE_STREAM ) - transform->minlen = transform->maclen; - else - { - /* - * GenericBlockCipher: - * 1. if EtM is in use: one block plus MAC - * otherwise: * first multiple of blocklen greater than maclen - * 2. IV except for SSL3 and TLS 1.0 - */ -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - if( session->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED ) - { - transform->minlen = transform->maclen - + cipher_info->block_size; - } - else -#endif - { - transform->minlen = transform->maclen - + cipher_info->block_size - - transform->maclen % cipher_info->block_size; - } - -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 || - ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_1 ) - ; /* No need to adjust minlen */ - else -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_2 || - ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) - { - transform->minlen += transform->ivlen; - } - else -#endif - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - } - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "keylen: %d, minlen: %d, ivlen: %d, maclen: %d", - transform->keylen, transform->minlen, transform->ivlen, - transform->maclen ) ); - - /* - * Finally setup the cipher contexts, IVs and MAC secrets. - */ -#if defined(MBEDTLS_SSL_CLI_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) - { - key1 = keyblk + mac_key_len * 2; - key2 = keyblk + mac_key_len * 2 + transform->keylen; - - mac_enc = keyblk; - mac_dec = keyblk + mac_key_len; - - /* - * This is not used in TLS v1.1. - */ - iv_copy_len = ( transform->fixed_ivlen ) ? - transform->fixed_ivlen : transform->ivlen; - memcpy( transform->iv_enc, key2 + transform->keylen, iv_copy_len ); - memcpy( transform->iv_dec, key2 + transform->keylen + iv_copy_len, - iv_copy_len ); - } - else -#endif /* MBEDTLS_SSL_CLI_C */ -#if defined(MBEDTLS_SSL_SRV_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) - { - key1 = keyblk + mac_key_len * 2 + transform->keylen; - key2 = keyblk + mac_key_len * 2; - - mac_enc = keyblk + mac_key_len; - mac_dec = keyblk; - - /* - * This is not used in TLS v1.1. - */ - iv_copy_len = ( transform->fixed_ivlen ) ? - transform->fixed_ivlen : transform->ivlen; - memcpy( transform->iv_dec, key1 + transform->keylen, iv_copy_len ); - memcpy( transform->iv_enc, key1 + transform->keylen + iv_copy_len, - iv_copy_len ); - } - else -#endif /* MBEDTLS_SSL_SRV_C */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - -#if defined(MBEDTLS_SSL_PROTO_SSL3) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) - { - if( mac_key_len > sizeof transform->mac_enc ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - memcpy( transform->mac_enc, mac_enc, mac_key_len ); - memcpy( transform->mac_dec, mac_dec, mac_key_len ); - } - else -#endif /* MBEDTLS_SSL_PROTO_SSL3 */ -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 ) - { - /* For HMAC-based ciphersuites, initialize the HMAC transforms. - For AEAD-based ciphersuites, there is nothing to do here. */ - if( mac_key_len != 0 ) - { - mbedtls_md_hmac_starts( &transform->md_ctx_enc, mac_enc, mac_key_len ); - mbedtls_md_hmac_starts( &transform->md_ctx_dec, mac_dec, mac_key_len ); - } - } - else -#endif - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - -#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) - if( mbedtls_ssl_hw_record_init != NULL ) - { - int ret = 0; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_init()" ) ); - - if( ( ret = mbedtls_ssl_hw_record_init( ssl, key1, key2, transform->keylen, - transform->iv_enc, transform->iv_dec, - iv_copy_len, - mac_enc, mac_dec, - mac_key_len ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_init", ret ); - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - } - } -#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ - -#if defined(MBEDTLS_SSL_EXPORT_KEYS) - if( ssl->conf->f_export_keys != NULL ) - { - ssl->conf->f_export_keys( ssl->conf->p_export_keys, - session->master, keyblk, - mac_key_len, transform->keylen, - iv_copy_len ); - } -#endif - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - - /* Only use PSA-based ciphers for TLS-1.2. - * That's relevant at least for TLS-1.0, where - * we assume that mbedtls_cipher_crypt() updates - * the structure field for the IV, which the PSA-based - * implementation currently doesn't. */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) - { - ret = mbedtls_cipher_setup_psa( &transform->cipher_ctx_enc, - cipher_info, taglen ); - if( ret != 0 && ret != MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup_psa", ret ); - return( ret ); - } - - if( ret == 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "Successfully setup PSA-based encryption cipher context" ) ); - psa_fallthrough = 0; - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "Failed to setup PSA-based cipher context for record encryption - fall through to default setup." ) ); - psa_fallthrough = 1; - } - } - else - psa_fallthrough = 1; -#else - psa_fallthrough = 1; -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - - if( psa_fallthrough == 1 ) -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_enc, - cipher_info ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup", ret ); - return( ret ); - } - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - /* Only use PSA-based ciphers for TLS-1.2. - * That's relevant at least for TLS-1.0, where - * we assume that mbedtls_cipher_crypt() updates - * the structure field for the IV, which the PSA-based - * implementation currently doesn't. */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) - { - ret = mbedtls_cipher_setup_psa( &transform->cipher_ctx_dec, - cipher_info, taglen ); - if( ret != 0 && ret != MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup_psa", ret ); - return( ret ); - } - - if( ret == 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "Successfully setup PSA-based decryption cipher context" ) ); - psa_fallthrough = 0; - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "Failed to setup PSA-based cipher context for record decryption - fall through to default setup." ) ); - psa_fallthrough = 1; - } - } - else - psa_fallthrough = 1; -#else - psa_fallthrough = 1; -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - - if( psa_fallthrough == 1 ) -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_dec, - cipher_info ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup", ret ); - return( ret ); - } - - if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx_enc, key1, - cipher_info->key_bitlen, - MBEDTLS_ENCRYPT ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret ); - return( ret ); - } - - if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx_dec, key2, - cipher_info->key_bitlen, - MBEDTLS_DECRYPT ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret ); - return( ret ); - } - -#if defined(MBEDTLS_CIPHER_MODE_CBC) - if( cipher_info->mode == MBEDTLS_MODE_CBC ) - { - if( ( ret = mbedtls_cipher_set_padding_mode( &transform->cipher_ctx_enc, - MBEDTLS_PADDING_NONE ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_set_padding_mode", ret ); - return( ret ); - } - - if( ( ret = mbedtls_cipher_set_padding_mode( &transform->cipher_ctx_dec, - MBEDTLS_PADDING_NONE ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_set_padding_mode", ret ); - return( ret ); - } - } -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - - mbedtls_platform_zeroize( keyblk, sizeof( keyblk ) ); - -#if defined(MBEDTLS_ZLIB_SUPPORT) - // Initialize compression - // - if( session->compression == MBEDTLS_SSL_COMPRESS_DEFLATE ) - { - if( ssl->compress_buf == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "Allocating compression buffer" ) ); - ssl->compress_buf = mbedtls_calloc( 1, MBEDTLS_SSL_COMPRESS_BUFFER_LEN ); - if( ssl->compress_buf == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", - MBEDTLS_SSL_COMPRESS_BUFFER_LEN ) ); - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - } - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "Initializing zlib states" ) ); - - memset( &transform->ctx_deflate, 0, sizeof( transform->ctx_deflate ) ); - memset( &transform->ctx_inflate, 0, sizeof( transform->ctx_inflate ) ); - - if( deflateInit( &transform->ctx_deflate, - Z_DEFAULT_COMPRESSION ) != Z_OK || - inflateInit( &transform->ctx_inflate ) != Z_OK ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "Failed to initialize compression" ) ); - return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED ); - } - } -#endif /* MBEDTLS_ZLIB_SUPPORT */ - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= derive keys" ) ); - - return( 0 ); -} - -#if defined(MBEDTLS_SSL_PROTO_SSL3) -void ssl_calc_verify_ssl( mbedtls_ssl_context *ssl, unsigned char hash[36] ) -{ - mbedtls_md5_context md5; - mbedtls_sha1_context sha1; - unsigned char pad_1[48]; - unsigned char pad_2[48]; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify ssl" ) ); - - mbedtls_md5_init( &md5 ); - mbedtls_sha1_init( &sha1 ); - - mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 ); - mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 ); - - memset( pad_1, 0x36, 48 ); - memset( pad_2, 0x5C, 48 ); - - mbedtls_md5_update_ret( &md5, ssl->session_negotiate->master, 48 ); - mbedtls_md5_update_ret( &md5, pad_1, 48 ); - mbedtls_md5_finish_ret( &md5, hash ); - - mbedtls_md5_starts_ret( &md5 ); - mbedtls_md5_update_ret( &md5, ssl->session_negotiate->master, 48 ); - mbedtls_md5_update_ret( &md5, pad_2, 48 ); - mbedtls_md5_update_ret( &md5, hash, 16 ); - mbedtls_md5_finish_ret( &md5, hash ); - - mbedtls_sha1_update_ret( &sha1, ssl->session_negotiate->master, 48 ); - mbedtls_sha1_update_ret( &sha1, pad_1, 40 ); - mbedtls_sha1_finish_ret( &sha1, hash + 16 ); - - mbedtls_sha1_starts_ret( &sha1 ); - mbedtls_sha1_update_ret( &sha1, ssl->session_negotiate->master, 48 ); - mbedtls_sha1_update_ret( &sha1, pad_2, 40 ); - mbedtls_sha1_update_ret( &sha1, hash + 16, 20 ); - mbedtls_sha1_finish_ret( &sha1, hash + 16 ); - - MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 ); - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); - - mbedtls_md5_free( &md5 ); - mbedtls_sha1_free( &sha1 ); - - return; -} -#endif /* MBEDTLS_SSL_PROTO_SSL3 */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) -void ssl_calc_verify_tls( mbedtls_ssl_context *ssl, unsigned char hash[36] ) -{ - mbedtls_md5_context md5; - mbedtls_sha1_context sha1; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify tls" ) ); - - mbedtls_md5_init( &md5 ); - mbedtls_sha1_init( &sha1 ); - - mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 ); - mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 ); - - mbedtls_md5_finish_ret( &md5, hash ); - mbedtls_sha1_finish_ret( &sha1, hash + 16 ); - - MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 ); - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); - - mbedtls_md5_free( &md5 ); - mbedtls_sha1_free( &sha1 ); - - return; -} -#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_SHA256_C) -void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *ssl, unsigned char hash[32] ) -{ -#if defined(MBEDTLS_USE_PSA_CRYPTO) - size_t hash_size; - psa_status_t status; - psa_hash_operation_t sha256_psa = psa_hash_operation_init(); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> PSA calc verify sha256" ) ); - status = psa_hash_clone( &ssl->handshake->fin_sha256_psa, &sha256_psa ); - if( status != PSA_SUCCESS ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash clone failed" ) ); - return; - } - - status = psa_hash_finish( &sha256_psa, hash, 32, &hash_size ); - if( status != PSA_SUCCESS ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash finish failed" ) ); - return; - } - MBEDTLS_SSL_DEBUG_BUF( 3, "PSA calculated verify result", hash, 32 ); - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= PSA calc verify" ) ); -#else - mbedtls_sha256_context sha256; - - mbedtls_sha256_init( &sha256 ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify sha256" ) ); - - mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 ); - mbedtls_sha256_finish_ret( &sha256, hash ); - - MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 32 ); - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); - - mbedtls_sha256_free( &sha256 ); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - return; -} -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) -void ssl_calc_verify_tls_sha384( mbedtls_ssl_context *ssl, unsigned char hash[48] ) -{ -#if defined(MBEDTLS_USE_PSA_CRYPTO) - size_t hash_size; - psa_status_t status; - psa_hash_operation_t sha384_psa = psa_hash_operation_init(); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> PSA calc verify sha384" ) ); - status = psa_hash_clone( &ssl->handshake->fin_sha384_psa, &sha384_psa ); - if( status != PSA_SUCCESS ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash clone failed" ) ); - return; - } - - status = psa_hash_finish( &sha384_psa, hash, 48, &hash_size ); - if( status != PSA_SUCCESS ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash finish failed" ) ); - return; - } - MBEDTLS_SSL_DEBUG_BUF( 3, "PSA calculated verify result", hash, 48 ); - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= PSA calc verify" ) ); -#else - mbedtls_sha512_context sha512; - - mbedtls_sha512_init( &sha512 ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify sha384" ) ); - - mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 ); - mbedtls_sha512_finish_ret( &sha512, hash ); - - MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 48 ); - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); - - mbedtls_sha512_free( &sha512 ); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - return; -} -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) -int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exchange_type_t key_ex ) -{ - unsigned char *p = ssl->handshake->premaster; - unsigned char *end = p + sizeof( ssl->handshake->premaster ); - const unsigned char *psk = ssl->conf->psk; - size_t psk_len = ssl->conf->psk_len; - - /* If the psk callback was called, use its result */ - if( ssl->handshake->psk != NULL ) - { - psk = ssl->handshake->psk; - psk_len = ssl->handshake->psk_len; - } - - /* - * PMS = struct { - * opaque other_secret<0..2^16-1>; - * opaque psk<0..2^16-1>; - * }; - * with "other_secret" depending on the particular key exchange - */ -#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) - if( key_ex == MBEDTLS_KEY_EXCHANGE_PSK ) - { - if( end - p < 2 ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - *(p++) = (unsigned char)( psk_len >> 8 ); - *(p++) = (unsigned char)( psk_len ); - - if( end < p || (size_t)( end - p ) < psk_len ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - memset( p, 0, psk_len ); - p += psk_len; - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) - if( key_ex == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) - { - /* - * other_secret already set by the ClientKeyExchange message, - * and is 48 bytes long - */ - if( end - p < 2 ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - *p++ = 0; - *p++ = 48; - p += 48; - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) - if( key_ex == MBEDTLS_KEY_EXCHANGE_DHE_PSK ) - { - int ret; - size_t len; - - /* Write length only when we know the actual value */ - if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx, - p + 2, end - ( p + 2 ), &len, - ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret ); - return( ret ); - } - *(p++) = (unsigned char)( len >> 8 ); - *(p++) = (unsigned char)( len ); - p += len; - - MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K ); - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) - if( key_ex == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) - { - int ret; - size_t zlen; - - if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx, &zlen, - p + 2, end - ( p + 2 ), - ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret ); - return( ret ); - } - - *(p++) = (unsigned char)( zlen >> 8 ); - *(p++) = (unsigned char)( zlen ); - p += zlen; - - MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, - MBEDTLS_DEBUG_ECDH_Z ); - } - else -#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - /* opaque psk<0..2^16-1>; */ - if( end - p < 2 ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - *(p++) = (unsigned char)( psk_len >> 8 ); - *(p++) = (unsigned char)( psk_len ); - - if( end < p || (size_t)( end - p ) < psk_len ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - memcpy( p, psk, psk_len ); - p += psk_len; - - ssl->handshake->pmslen = p - ssl->handshake->premaster; - - return( 0 ); -} -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ - -#if defined(MBEDTLS_SSL_PROTO_SSL3) -/* - * SSLv3.0 MAC functions - */ -#define SSL_MAC_MAX_BYTES 20 /* MD-5 or SHA-1 */ -static void ssl_mac( mbedtls_md_context_t *md_ctx, - const unsigned char *secret, - const unsigned char *buf, size_t len, - const unsigned char *ctr, int type, - unsigned char out[SSL_MAC_MAX_BYTES] ) -{ - unsigned char header[11]; - unsigned char padding[48]; - int padlen; - int md_size = mbedtls_md_get_size( md_ctx->md_info ); - int md_type = mbedtls_md_get_type( md_ctx->md_info ); - - /* Only MD5 and SHA-1 supported */ - if( md_type == MBEDTLS_MD_MD5 ) - padlen = 48; - else - padlen = 40; - - memcpy( header, ctr, 8 ); - header[ 8] = (unsigned char) type; - header[ 9] = (unsigned char)( len >> 8 ); - header[10] = (unsigned char)( len ); - - memset( padding, 0x36, padlen ); - mbedtls_md_starts( md_ctx ); - mbedtls_md_update( md_ctx, secret, md_size ); - mbedtls_md_update( md_ctx, padding, padlen ); - mbedtls_md_update( md_ctx, header, 11 ); - mbedtls_md_update( md_ctx, buf, len ); - mbedtls_md_finish( md_ctx, out ); - - memset( padding, 0x5C, padlen ); - mbedtls_md_starts( md_ctx ); - mbedtls_md_update( md_ctx, secret, md_size ); - mbedtls_md_update( md_ctx, padding, padlen ); - mbedtls_md_update( md_ctx, out, md_size ); - mbedtls_md_finish( md_ctx, out ); -} -#endif /* MBEDTLS_SSL_PROTO_SSL3 */ - -#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) || \ - ( defined(MBEDTLS_CIPHER_MODE_CBC) && \ - ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) || defined(MBEDTLS_ARIA_C)) ) -#define SSL_SOME_MODES_USE_MAC -#endif - -/* The function below is only used in the Lucky 13 counter-measure in - * ssl_decrypt_buf(). These are the defines that guard the call site. */ -#if defined(SSL_SOME_MODES_USE_MAC) && \ - ( defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) ) -/* This function makes sure every byte in the memory region is accessed - * (in ascending addresses order) */ -static void ssl_read_memory( unsigned char *p, size_t len ) -{ - unsigned char acc = 0; - volatile unsigned char force; - - for( ; len != 0; p++, len-- ) - acc ^= *p; - - force = acc; - (void) force; -} -#endif /* SSL_SOME_MODES_USE_MAC && ( TLS1 || TLS1_1 || TLS1_2 ) */ - -/* - * Encryption/decryption functions - */ -static int ssl_encrypt_buf( mbedtls_ssl_context *ssl ) -{ - mbedtls_cipher_mode_t mode; - int auth_done = 0; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> encrypt buf" ) ); - - if( ssl->session_out == NULL || ssl->transform_out == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - mode = mbedtls_cipher_get_cipher_mode( &ssl->transform_out->cipher_ctx_enc ); - - MBEDTLS_SSL_DEBUG_BUF( 4, "before encrypt: output payload", - ssl->out_msg, ssl->out_msglen ); - - /* - * Add MAC before if needed - */ -#if defined(SSL_SOME_MODES_USE_MAC) - if( mode == MBEDTLS_MODE_STREAM || - ( mode == MBEDTLS_MODE_CBC -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - && ssl->session_out->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED -#endif - ) ) - { -#if defined(MBEDTLS_SSL_PROTO_SSL3) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) - { - unsigned char mac[SSL_MAC_MAX_BYTES]; - - ssl_mac( &ssl->transform_out->md_ctx_enc, - ssl->transform_out->mac_enc, - ssl->out_msg, ssl->out_msglen, - ssl->out_ctr, ssl->out_msgtype, - mac ); - - memcpy( ssl->out_msg + ssl->out_msglen, mac, ssl->transform_out->maclen ); - } - else -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 ) - { - unsigned char mac[MBEDTLS_SSL_MAC_ADD]; - - mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_ctr, 8 ); - mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_hdr, 3 ); - mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_len, 2 ); - mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, - ssl->out_msg, ssl->out_msglen ); - mbedtls_md_hmac_finish( &ssl->transform_out->md_ctx_enc, mac ); - mbedtls_md_hmac_reset( &ssl->transform_out->md_ctx_enc ); - - memcpy( ssl->out_msg + ssl->out_msglen, mac, ssl->transform_out->maclen ); - } - else -#endif - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - MBEDTLS_SSL_DEBUG_BUF( 4, "computed mac", - ssl->out_msg + ssl->out_msglen, - ssl->transform_out->maclen ); - - ssl->out_msglen += ssl->transform_out->maclen; - auth_done++; - } -#endif /* AEAD not the only option */ - - /* - * Encrypt - */ -#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) - if( mode == MBEDTLS_MODE_STREAM ) - { - int ret; - size_t olen = 0; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, " - "including %d bytes of padding", - ssl->out_msglen, 0 ) ); - - if( ( ret = mbedtls_cipher_crypt( &ssl->transform_out->cipher_ctx_enc, - ssl->transform_out->iv_enc, - ssl->transform_out->ivlen, - ssl->out_msg, ssl->out_msglen, - ssl->out_msg, &olen ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret ); - return( ret ); - } - - if( ssl->out_msglen != olen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - } - else -#endif /* MBEDTLS_ARC4_C || MBEDTLS_CIPHER_NULL_CIPHER */ -#if defined(MBEDTLS_GCM_C) || \ - defined(MBEDTLS_CCM_C) || \ - defined(MBEDTLS_CHACHAPOLY_C) - if( mode == MBEDTLS_MODE_GCM || - mode == MBEDTLS_MODE_CCM || - mode == MBEDTLS_MODE_CHACHAPOLY ) - { - int ret; - size_t enc_msglen, olen; - unsigned char *enc_msg; - unsigned char add_data[13]; - unsigned char iv[12]; - mbedtls_ssl_transform *transform = ssl->transform_out; - unsigned char taglen = transform->ciphersuite_info->flags & - MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16; - size_t explicit_ivlen = transform->ivlen - transform->fixed_ivlen; - - /* - * Prepare additional authenticated data - */ - memcpy( add_data, ssl->out_ctr, 8 ); - add_data[8] = ssl->out_msgtype; - mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver, - ssl->conf->transport, add_data + 9 ); - add_data[11] = ( ssl->out_msglen >> 8 ) & 0xFF; - add_data[12] = ssl->out_msglen & 0xFF; - - MBEDTLS_SSL_DEBUG_BUF( 4, "additional data for AEAD", add_data, 13 ); - - /* - * Generate IV - */ - if( transform->ivlen == 12 && transform->fixed_ivlen == 4 ) - { - /* GCM and CCM: fixed || explicit (=seqnum) */ - memcpy( iv, transform->iv_enc, transform->fixed_ivlen ); - memcpy( iv + transform->fixed_ivlen, ssl->out_ctr, 8 ); - memcpy( ssl->out_iv, ssl->out_ctr, 8 ); - - } - else if( transform->ivlen == 12 && transform->fixed_ivlen == 12 ) - { - /* ChachaPoly: fixed XOR sequence number */ - unsigned char i; - - memcpy( iv, transform->iv_enc, transform->fixed_ivlen ); - - for( i = 0; i < 8; i++ ) - iv[i+4] ^= ssl->out_ctr[i]; - } - else - { - /* Reminder if we ever add an AEAD mode with a different size */ - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - MBEDTLS_SSL_DEBUG_BUF( 4, "IV used (internal)", - iv, transform->ivlen ); - MBEDTLS_SSL_DEBUG_BUF( 4, "IV used (transmitted)", - ssl->out_iv, explicit_ivlen ); - - /* - * Fix message length with added IV - */ - enc_msg = ssl->out_msg; - enc_msglen = ssl->out_msglen; - ssl->out_msglen += explicit_ivlen; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, " - "including 0 bytes of padding", - ssl->out_msglen ) ); - - /* - * Encrypt and authenticate - */ - if( ( ret = mbedtls_cipher_auth_encrypt( &transform->cipher_ctx_enc, - iv, transform->ivlen, - add_data, 13, - enc_msg, enc_msglen, - enc_msg, &olen, - enc_msg + enc_msglen, taglen ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_encrypt", ret ); - return( ret ); - } - - if( olen != enc_msglen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - ssl->out_msglen += taglen; - auth_done++; - - MBEDTLS_SSL_DEBUG_BUF( 4, "after encrypt: tag", enc_msg + enc_msglen, taglen ); - } - else -#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */ -#if defined(MBEDTLS_CIPHER_MODE_CBC) && \ - ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) || defined(MBEDTLS_ARIA_C) ) - if( mode == MBEDTLS_MODE_CBC ) - { - int ret; - unsigned char *enc_msg; - size_t enc_msglen, padlen, olen = 0, i; - - padlen = ssl->transform_out->ivlen - ( ssl->out_msglen + 1 ) % - ssl->transform_out->ivlen; - if( padlen == ssl->transform_out->ivlen ) - padlen = 0; - - for( i = 0; i <= padlen; i++ ) - ssl->out_msg[ssl->out_msglen + i] = (unsigned char) padlen; - - ssl->out_msglen += padlen + 1; - - enc_msglen = ssl->out_msglen; - enc_msg = ssl->out_msg; - -#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) - /* - * Prepend per-record IV for block cipher in TLS v1.1 and up as per - * Method 1 (6.2.3.2. in RFC4346 and RFC5246) - */ - if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) - { - /* - * Generate IV - */ - ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->transform_out->iv_enc, - ssl->transform_out->ivlen ); - if( ret != 0 ) - return( ret ); - - memcpy( ssl->out_iv, ssl->transform_out->iv_enc, - ssl->transform_out->ivlen ); - - /* - * Fix pointer positions and message length with added IV - */ - enc_msg = ssl->out_msg; - enc_msglen = ssl->out_msglen; - ssl->out_msglen += ssl->transform_out->ivlen; - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */ - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, " - "including %d bytes of IV and %d bytes of padding", - ssl->out_msglen, ssl->transform_out->ivlen, - padlen + 1 ) ); - - if( ( ret = mbedtls_cipher_crypt( &ssl->transform_out->cipher_ctx_enc, - ssl->transform_out->iv_enc, - ssl->transform_out->ivlen, - enc_msg, enc_msglen, - enc_msg, &olen ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret ); - return( ret ); - } - - if( enc_msglen != olen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) - if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 ) - { - /* - * Save IV in SSL3 and TLS1 - */ - memcpy( ssl->transform_out->iv_enc, - ssl->transform_out->cipher_ctx_enc.iv, - ssl->transform_out->ivlen ); - } -#endif - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - if( auth_done == 0 ) - { - unsigned char mac[MBEDTLS_SSL_MAC_ADD]; - - /* - * MAC(MAC_write_key, seq_num + - * TLSCipherText.type + - * TLSCipherText.version + - * length_of( (IV +) ENC(...) ) + - * IV + // except for TLS 1.0 - * ENC(content + padding + padding_length)); - */ - unsigned char pseudo_hdr[13]; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) ); - - memcpy( pseudo_hdr + 0, ssl->out_ctr, 8 ); - memcpy( pseudo_hdr + 8, ssl->out_hdr, 3 ); - pseudo_hdr[11] = (unsigned char)( ( ssl->out_msglen >> 8 ) & 0xFF ); - pseudo_hdr[12] = (unsigned char)( ( ssl->out_msglen ) & 0xFF ); - - MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", pseudo_hdr, 13 ); - - mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, pseudo_hdr, 13 ); - mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, - ssl->out_iv, ssl->out_msglen ); - mbedtls_md_hmac_finish( &ssl->transform_out->md_ctx_enc, mac ); - mbedtls_md_hmac_reset( &ssl->transform_out->md_ctx_enc ); - - memcpy( ssl->out_iv + ssl->out_msglen, mac, - ssl->transform_out->maclen ); - - ssl->out_msglen += ssl->transform_out->maclen; - auth_done++; - } -#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ - } - else -#endif /* MBEDTLS_CIPHER_MODE_CBC && - ( MBEDTLS_AES_C || MBEDTLS_CAMELLIA_C || MBEDTLS_ARIA_C ) */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - /* Make extra sure authentication was performed, exactly once */ - if( auth_done != 1 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= encrypt buf" ) ); - - return( 0 ); -} - -static int ssl_decrypt_buf( mbedtls_ssl_context *ssl ) -{ - mbedtls_cipher_mode_t mode; - int auth_done = 0; -#if defined(SSL_SOME_MODES_USE_MAC) - size_t padlen = 0, correct = 1; -#endif - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> decrypt buf" ) ); - - if( ssl->session_in == NULL || ssl->transform_in == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - mode = mbedtls_cipher_get_cipher_mode( &ssl->transform_in->cipher_ctx_dec ); - - if( ssl->in_msglen < ssl->transform_in->minlen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "in_msglen (%d) < minlen (%d)", - ssl->in_msglen, ssl->transform_in->minlen ) ); - return( MBEDTLS_ERR_SSL_INVALID_MAC ); - } - -#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) - if( mode == MBEDTLS_MODE_STREAM ) - { - int ret; - size_t olen = 0; - - padlen = 0; - - if( ( ret = mbedtls_cipher_crypt( &ssl->transform_in->cipher_ctx_dec, - ssl->transform_in->iv_dec, - ssl->transform_in->ivlen, - ssl->in_msg, ssl->in_msglen, - ssl->in_msg, &olen ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret ); - return( ret ); - } - - if( ssl->in_msglen != olen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - } - else -#endif /* MBEDTLS_ARC4_C || MBEDTLS_CIPHER_NULL_CIPHER */ -#if defined(MBEDTLS_GCM_C) || \ - defined(MBEDTLS_CCM_C) || \ - defined(MBEDTLS_CHACHAPOLY_C) - if( mode == MBEDTLS_MODE_GCM || - mode == MBEDTLS_MODE_CCM || - mode == MBEDTLS_MODE_CHACHAPOLY ) - { - int ret; - size_t dec_msglen, olen; - unsigned char *dec_msg; - unsigned char *dec_msg_result; - unsigned char add_data[13]; - unsigned char iv[12]; - mbedtls_ssl_transform *transform = ssl->transform_in; - unsigned char taglen = transform->ciphersuite_info->flags & - MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16; - size_t explicit_iv_len = transform->ivlen - transform->fixed_ivlen; - - /* - * Compute and update sizes - */ - if( ssl->in_msglen < explicit_iv_len + taglen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < explicit_iv_len (%d) " - "+ taglen (%d)", ssl->in_msglen, - explicit_iv_len, taglen ) ); - return( MBEDTLS_ERR_SSL_INVALID_MAC ); - } - dec_msglen = ssl->in_msglen - explicit_iv_len - taglen; - - dec_msg = ssl->in_msg; - dec_msg_result = ssl->in_msg; - ssl->in_msglen = dec_msglen; - - /* - * Prepare additional authenticated data - */ - memcpy( add_data, ssl->in_ctr, 8 ); - add_data[8] = ssl->in_msgtype; - mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver, - ssl->conf->transport, add_data + 9 ); - add_data[11] = ( ssl->in_msglen >> 8 ) & 0xFF; - add_data[12] = ssl->in_msglen & 0xFF; - - MBEDTLS_SSL_DEBUG_BUF( 4, "additional data for AEAD", add_data, 13 ); - - /* - * Prepare IV - */ - if( transform->ivlen == 12 && transform->fixed_ivlen == 4 ) - { - /* GCM and CCM: fixed || explicit (transmitted) */ - memcpy( iv, transform->iv_dec, transform->fixed_ivlen ); - memcpy( iv + transform->fixed_ivlen, ssl->in_iv, 8 ); - - } - else if( transform->ivlen == 12 && transform->fixed_ivlen == 12 ) - { - /* ChachaPoly: fixed XOR sequence number */ - unsigned char i; - - memcpy( iv, transform->iv_dec, transform->fixed_ivlen ); - - for( i = 0; i < 8; i++ ) - iv[i+4] ^= ssl->in_ctr[i]; - } - else - { - /* Reminder if we ever add an AEAD mode with a different size */ - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - MBEDTLS_SSL_DEBUG_BUF( 4, "IV used", iv, transform->ivlen ); - MBEDTLS_SSL_DEBUG_BUF( 4, "TAG used", dec_msg + dec_msglen, taglen ); - - /* - * Decrypt and authenticate - */ - if( ( ret = mbedtls_cipher_auth_decrypt( &ssl->transform_in->cipher_ctx_dec, - iv, transform->ivlen, - add_data, 13, - dec_msg, dec_msglen, - dec_msg_result, &olen, - dec_msg + dec_msglen, taglen ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_decrypt", ret ); - - if( ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED ) - return( MBEDTLS_ERR_SSL_INVALID_MAC ); - - return( ret ); - } - auth_done++; - - if( olen != dec_msglen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - } - else -#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */ -#if defined(MBEDTLS_CIPHER_MODE_CBC) && \ - ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) || defined(MBEDTLS_ARIA_C) ) - if( mode == MBEDTLS_MODE_CBC ) - { - /* - * Decrypt and check the padding - */ - int ret; - unsigned char *dec_msg; - unsigned char *dec_msg_result; - size_t dec_msglen; - size_t minlen = 0; - size_t olen = 0; - - /* - * Check immediate ciphertext sanity - */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) - minlen += ssl->transform_in->ivlen; -#endif - - if( ssl->in_msglen < minlen + ssl->transform_in->ivlen || - ssl->in_msglen < minlen + ssl->transform_in->maclen + 1 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < max( ivlen(%d), maclen (%d) " - "+ 1 ) ( + expl IV )", ssl->in_msglen, - ssl->transform_in->ivlen, - ssl->transform_in->maclen ) ); - return( MBEDTLS_ERR_SSL_INVALID_MAC ); - } - - dec_msglen = ssl->in_msglen; - dec_msg = ssl->in_msg; - dec_msg_result = ssl->in_msg; - - /* - * Authenticate before decrypt if enabled - */ -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - if( ssl->session_in->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED ) - { - unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD]; - unsigned char pseudo_hdr[13]; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) ); - - dec_msglen -= ssl->transform_in->maclen; - ssl->in_msglen -= ssl->transform_in->maclen; - - memcpy( pseudo_hdr + 0, ssl->in_ctr, 8 ); - memcpy( pseudo_hdr + 8, ssl->in_hdr, 3 ); - pseudo_hdr[11] = (unsigned char)( ( ssl->in_msglen >> 8 ) & 0xFF ); - pseudo_hdr[12] = (unsigned char)( ( ssl->in_msglen ) & 0xFF ); - - MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", pseudo_hdr, 13 ); - - mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, pseudo_hdr, 13 ); - mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, - ssl->in_iv, ssl->in_msglen ); - mbedtls_md_hmac_finish( &ssl->transform_in->md_ctx_dec, mac_expect ); - mbedtls_md_hmac_reset( &ssl->transform_in->md_ctx_dec ); - - MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", ssl->in_iv + ssl->in_msglen, - ssl->transform_in->maclen ); - MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect, - ssl->transform_in->maclen ); - - if( mbedtls_ssl_safer_memcmp( ssl->in_iv + ssl->in_msglen, mac_expect, - ssl->transform_in->maclen ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) ); - - return( MBEDTLS_ERR_SSL_INVALID_MAC ); - } - auth_done++; - } -#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ - - /* - * Check length sanity - */ - if( ssl->in_msglen % ssl->transform_in->ivlen != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) %% ivlen (%d) != 0", - ssl->in_msglen, ssl->transform_in->ivlen ) ); - return( MBEDTLS_ERR_SSL_INVALID_MAC ); - } - -#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) - /* - * Initialize for prepended IV for block cipher in TLS v1.1 and up - */ - if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) - { - unsigned char i; - dec_msglen -= ssl->transform_in->ivlen; - ssl->in_msglen -= ssl->transform_in->ivlen; - - for( i = 0; i < ssl->transform_in->ivlen; i++ ) - ssl->transform_in->iv_dec[i] = ssl->in_iv[i]; - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */ - - if( ( ret = mbedtls_cipher_crypt( &ssl->transform_in->cipher_ctx_dec, - ssl->transform_in->iv_dec, - ssl->transform_in->ivlen, - dec_msg, dec_msglen, - dec_msg_result, &olen ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret ); - return( ret ); - } - - if( dec_msglen != olen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) - if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 ) - { - /* - * Save IV in SSL3 and TLS1 - */ - memcpy( ssl->transform_in->iv_dec, - ssl->transform_in->cipher_ctx_dec.iv, - ssl->transform_in->ivlen ); - } -#endif - - padlen = 1 + ssl->in_msg[ssl->in_msglen - 1]; - - if( ssl->in_msglen < ssl->transform_in->maclen + padlen && - auth_done == 0 ) - { -#if defined(MBEDTLS_SSL_DEBUG_ALL) - MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < maclen (%d) + padlen (%d)", - ssl->in_msglen, ssl->transform_in->maclen, padlen ) ); -#endif - padlen = 0; - correct = 0; - } - -#if defined(MBEDTLS_SSL_PROTO_SSL3) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) - { - if( padlen > ssl->transform_in->ivlen ) - { -#if defined(MBEDTLS_SSL_DEBUG_ALL) - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding length: is %d, " - "should be no more than %d", - padlen, ssl->transform_in->ivlen ) ); -#endif - correct = 0; - } - } - else -#endif /* MBEDTLS_SSL_PROTO_SSL3 */ -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 ) - { - /* - * TLSv1+: always check the padding up to the first failure - * and fake check up to 256 bytes of padding - */ - size_t pad_count = 0, real_count = 1; - size_t padding_idx = ssl->in_msglen - padlen; - size_t i; - - /* - * Padding is guaranteed to be incorrect if: - * 1. padlen > ssl->in_msglen - * - * 2. padding_idx > MBEDTLS_SSL_IN_CONTENT_LEN + - * ssl->transform_in->maclen - * - * In both cases we reset padding_idx to a safe value (0) to - * prevent out-of-buffer reads. - */ - correct &= ( padlen <= ssl->in_msglen ); - correct &= ( padding_idx <= MBEDTLS_SSL_IN_CONTENT_LEN + - ssl->transform_in->maclen ); - - padding_idx *= correct; - - for( i = 0; i < 256; i++ ) - { - real_count &= ( i < padlen ); - pad_count += real_count * - ( ssl->in_msg[padding_idx + i] == padlen - 1 ); - } - - correct &= ( pad_count == padlen ); /* Only 1 on correct padding */ - -#if defined(MBEDTLS_SSL_DEBUG_ALL) - if( padlen > 0 && correct == 0 ) - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding byte detected" ) ); -#endif - padlen &= correct * 0x1FF; - } - else -#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ - MBEDTLS_SSL_PROTO_TLS1_2 */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - ssl->in_msglen -= padlen; - } - else -#endif /* MBEDTLS_CIPHER_MODE_CBC && - ( MBEDTLS_AES_C || MBEDTLS_CAMELLIA_C || MBEDTLS_ARIA_C ) */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - -#if defined(MBEDTLS_SSL_DEBUG_ALL) - MBEDTLS_SSL_DEBUG_BUF( 4, "raw buffer after decryption", - ssl->in_msg, ssl->in_msglen ); -#endif - - /* - * Authenticate if not done yet. - * Compute the MAC regardless of the padding result (RFC4346, CBCTIME). - */ -#if defined(SSL_SOME_MODES_USE_MAC) - if( auth_done == 0 ) - { - unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD]; - - ssl->in_msglen -= ssl->transform_in->maclen; - - ssl->in_len[0] = (unsigned char)( ssl->in_msglen >> 8 ); - ssl->in_len[1] = (unsigned char)( ssl->in_msglen ); - -#if defined(MBEDTLS_SSL_PROTO_SSL3) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) - { - ssl_mac( &ssl->transform_in->md_ctx_dec, - ssl->transform_in->mac_dec, - ssl->in_msg, ssl->in_msglen, - ssl->in_ctr, ssl->in_msgtype, - mac_expect ); - } - else -#endif /* MBEDTLS_SSL_PROTO_SSL3 */ -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 ) - { - /* - * Process MAC and always update for padlen afterwards to make - * total time independent of padlen. - * - * Known timing attacks: - * - Lucky Thirteen (http://www.isg.rhul.ac.uk/tls/TLStiming.pdf) - * - * To compensate for different timings for the MAC calculation - * depending on how much padding was removed (which is determined - * by padlen), process extra_run more blocks through the hash - * function. - * - * The formula in the paper is - * extra_run = ceil( (L1-55) / 64 ) - ceil( (L2-55) / 64 ) - * where L1 is the size of the header plus the decrypted message - * plus CBC padding and L2 is the size of the header plus the - * decrypted message. This is for an underlying hash function - * with 64-byte blocks. - * We use ( (Lx+8) / 64 ) to handle 'negative Lx' values - * correctly. We round down instead of up, so -56 is the correct - * value for our calculations instead of -55. - * - * Repeat the formula rather than defining a block_size variable. - * This avoids requiring division by a variable at runtime - * (which would be marginally less efficient and would require - * linking an extra division function in some builds). - */ - size_t j, extra_run = 0; - - /* - * The next two sizes are the minimum and maximum values of - * in_msglen over all padlen values. - * - * They're independent of padlen, since we previously did - * in_msglen -= padlen. - * - * Note that max_len + maclen is never more than the buffer - * length, as we previously did in_msglen -= maclen too. - */ - const size_t max_len = ssl->in_msglen + padlen; - const size_t min_len = ( max_len > 256 ) ? max_len - 256 : 0; - - switch( ssl->transform_in->ciphersuite_info->mac ) - { -#if defined(MBEDTLS_MD5_C) || defined(MBEDTLS_SHA1_C) || \ - defined(MBEDTLS_SHA256_C) - case MBEDTLS_MD_MD5: - case MBEDTLS_MD_SHA1: - case MBEDTLS_MD_SHA256: - /* 8 bytes of message size, 64-byte compression blocks */ - extra_run = ( 13 + ssl->in_msglen + padlen + 8 ) / 64 - - ( 13 + ssl->in_msglen + 8 ) / 64; - break; -#endif -#if defined(MBEDTLS_SHA512_C) - case MBEDTLS_MD_SHA384: - /* 16 bytes of message size, 128-byte compression blocks */ - extra_run = ( 13 + ssl->in_msglen + padlen + 16 ) / 128 - - ( 13 + ssl->in_msglen + 16 ) / 128; - break; -#endif - default: - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - extra_run &= correct * 0xFF; - - mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_ctr, 8 ); - mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_hdr, 3 ); - mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_len, 2 ); - mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_msg, - ssl->in_msglen ); - /* Make sure we access everything even when padlen > 0. This - * makes the synchronisation requirements for just-in-time - * Prime+Probe attacks much tighter and hopefully impractical. */ - ssl_read_memory( ssl->in_msg + ssl->in_msglen, padlen ); - mbedtls_md_hmac_finish( &ssl->transform_in->md_ctx_dec, mac_expect ); - - /* Call mbedtls_md_process at least once due to cache attacks - * that observe whether md_process() was called of not */ - for( j = 0; j < extra_run + 1; j++ ) - mbedtls_md_process( &ssl->transform_in->md_ctx_dec, ssl->in_msg ); - - mbedtls_md_hmac_reset( &ssl->transform_in->md_ctx_dec ); - - /* Make sure we access all the memory that could contain the MAC, - * before we check it in the next code block. This makes the - * synchronisation requirements for just-in-time Prime+Probe - * attacks much tighter and hopefully impractical. */ - ssl_read_memory( ssl->in_msg + min_len, - max_len - min_len + ssl->transform_in->maclen ); - } - else -#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ - MBEDTLS_SSL_PROTO_TLS1_2 */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - -#if defined(MBEDTLS_SSL_DEBUG_ALL) - MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect, ssl->transform_in->maclen ); - MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", ssl->in_msg + ssl->in_msglen, - ssl->transform_in->maclen ); -#endif - - if( mbedtls_ssl_safer_memcmp( ssl->in_msg + ssl->in_msglen, mac_expect, - ssl->transform_in->maclen ) != 0 ) - { -#if defined(MBEDTLS_SSL_DEBUG_ALL) - MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) ); -#endif - correct = 0; - } - auth_done++; - } - - /* - * Finally check the correct flag - */ - if( correct == 0 ) - return( MBEDTLS_ERR_SSL_INVALID_MAC ); -#endif /* SSL_SOME_MODES_USE_MAC */ - - /* Make extra sure authentication was performed, exactly once */ - if( auth_done != 1 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - if( ssl->in_msglen == 0 ) - { -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 - && ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA ) - { - /* TLS v1.2 explicitly disallows zero-length messages which are not application data */ - MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid zero-length message type: %d", ssl->in_msgtype ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - - ssl->nb_zero++; - - /* - * Three or more empty messages may be a DoS attack - * (excessive CPU consumption). - */ - if( ssl->nb_zero > 3 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "received four consecutive empty " - "messages, possible DoS attack" ) ); - return( MBEDTLS_ERR_SSL_INVALID_MAC ); - } - } - else - ssl->nb_zero = 0; - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - ; /* in_ctr read from peer, not maintained internally */ - } - else -#endif - { - unsigned char i; - for( i = 8; i > ssl_ep_len( ssl ); i-- ) - if( ++ssl->in_ctr[i - 1] != 0 ) - break; - - /* The loop goes to its end iff the counter is wrapping */ - if( i == ssl_ep_len( ssl ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "incoming message counter would wrap" ) ); - return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING ); - } - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= decrypt buf" ) ); - - return( 0 ); -} - -#undef MAC_NONE -#undef MAC_PLAINTEXT -#undef MAC_CIPHERTEXT - -#if defined(MBEDTLS_ZLIB_SUPPORT) -/* - * Compression/decompression functions - */ -static int ssl_compress_buf( mbedtls_ssl_context *ssl ) -{ - int ret; - unsigned char *msg_post = ssl->out_msg; - ptrdiff_t bytes_written = ssl->out_msg - ssl->out_buf; - size_t len_pre = ssl->out_msglen; - unsigned char *msg_pre = ssl->compress_buf; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> compress buf" ) ); - - if( len_pre == 0 ) - return( 0 ); - - memcpy( msg_pre, ssl->out_msg, len_pre ); - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "before compression: msglen = %d, ", - ssl->out_msglen ) ); - - MBEDTLS_SSL_DEBUG_BUF( 4, "before compression: output payload", - ssl->out_msg, ssl->out_msglen ); - - ssl->transform_out->ctx_deflate.next_in = msg_pre; - ssl->transform_out->ctx_deflate.avail_in = len_pre; - ssl->transform_out->ctx_deflate.next_out = msg_post; - ssl->transform_out->ctx_deflate.avail_out = MBEDTLS_SSL_OUT_BUFFER_LEN - bytes_written; - - ret = deflate( &ssl->transform_out->ctx_deflate, Z_SYNC_FLUSH ); - if( ret != Z_OK ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "failed to perform compression (%d)", ret ) ); - return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED ); - } - - ssl->out_msglen = MBEDTLS_SSL_OUT_BUFFER_LEN - - ssl->transform_out->ctx_deflate.avail_out - bytes_written; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "after compression: msglen = %d, ", - ssl->out_msglen ) ); - - MBEDTLS_SSL_DEBUG_BUF( 4, "after compression: output payload", - ssl->out_msg, ssl->out_msglen ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= compress buf" ) ); - - return( 0 ); -} - -static int ssl_decompress_buf( mbedtls_ssl_context *ssl ) -{ - int ret; - unsigned char *msg_post = ssl->in_msg; - ptrdiff_t header_bytes = ssl->in_msg - ssl->in_buf; - size_t len_pre = ssl->in_msglen; - unsigned char *msg_pre = ssl->compress_buf; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> decompress buf" ) ); - - if( len_pre == 0 ) - return( 0 ); - - memcpy( msg_pre, ssl->in_msg, len_pre ); - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "before decompression: msglen = %d, ", - ssl->in_msglen ) ); - - MBEDTLS_SSL_DEBUG_BUF( 4, "before decompression: input payload", - ssl->in_msg, ssl->in_msglen ); - - ssl->transform_in->ctx_inflate.next_in = msg_pre; - ssl->transform_in->ctx_inflate.avail_in = len_pre; - ssl->transform_in->ctx_inflate.next_out = msg_post; - ssl->transform_in->ctx_inflate.avail_out = MBEDTLS_SSL_IN_BUFFER_LEN - - header_bytes; - - ret = inflate( &ssl->transform_in->ctx_inflate, Z_SYNC_FLUSH ); - if( ret != Z_OK ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "failed to perform decompression (%d)", ret ) ); - return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED ); - } - - ssl->in_msglen = MBEDTLS_SSL_IN_BUFFER_LEN - - ssl->transform_in->ctx_inflate.avail_out - header_bytes; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "after decompression: msglen = %d, ", - ssl->in_msglen ) ); - - MBEDTLS_SSL_DEBUG_BUF( 4, "after decompression: input payload", - ssl->in_msg, ssl->in_msglen ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= decompress buf" ) ); - - return( 0 ); -} -#endif /* MBEDTLS_ZLIB_SUPPORT */ - -#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION) -static int ssl_write_hello_request( mbedtls_ssl_context *ssl ); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) -static int ssl_resend_hello_request( mbedtls_ssl_context *ssl ) -{ - /* If renegotiation is not enforced, retransmit until we would reach max - * timeout if we were using the usual handshake doubling scheme */ - if( ssl->conf->renego_max_records < 0 ) - { - uint32_t ratio = ssl->conf->hs_timeout_max / ssl->conf->hs_timeout_min + 1; - unsigned char doublings = 1; - - while( ratio != 0 ) - { - ++doublings; - ratio >>= 1; - } - - if( ++ssl->renego_records_seen > doublings ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "no longer retransmitting hello request" ) ); - return( 0 ); - } - } - - return( ssl_write_hello_request( ssl ) ); -} -#endif -#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */ - -/* - * Fill the input message buffer by appending data to it. - * The amount of data already fetched is in ssl->in_left. - * - * If we return 0, is it guaranteed that (at least) nb_want bytes are - * available (from this read and/or a previous one). Otherwise, an error code - * is returned (possibly EOF or WANT_READ). - * - * With stream transport (TLS) on success ssl->in_left == nb_want, but - * with datagram transport (DTLS) on success ssl->in_left >= nb_want, - * since we always read a whole datagram at once. - * - * For DTLS, it is up to the caller to set ssl->next_record_offset when - * they're done reading a record. - */ -int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ) -{ - int ret; - size_t len; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> fetch input" ) ); - - if( ssl->f_recv == NULL && ssl->f_recv_timeout == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() " - "or mbedtls_ssl_set_bio()" ) ); - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - if( nb_want > MBEDTLS_SSL_IN_BUFFER_LEN - (size_t)( ssl->in_hdr - ssl->in_buf ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "requesting more data than fits" ) ); - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - uint32_t timeout; - - /* Just to be sure */ - if( ssl->f_set_timer == NULL || ssl->f_get_timer == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "You must use " - "mbedtls_ssl_set_timer_cb() for DTLS" ) ); - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - /* - * The point is, we need to always read a full datagram at once, so we - * sometimes read more then requested, and handle the additional data. - * It could be the rest of the current record (while fetching the - * header) and/or some other records in the same datagram. - */ - - /* - * Move to the next record in the already read datagram if applicable - */ - if( ssl->next_record_offset != 0 ) - { - if( ssl->in_left < ssl->next_record_offset ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - ssl->in_left -= ssl->next_record_offset; - - if( ssl->in_left != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "next record in same datagram, offset: %d", - ssl->next_record_offset ) ); - memmove( ssl->in_hdr, - ssl->in_hdr + ssl->next_record_offset, - ssl->in_left ); - } - - ssl->next_record_offset = 0; - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d", - ssl->in_left, nb_want ) ); - - /* - * Done if we already have enough data. - */ - if( nb_want <= ssl->in_left) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= fetch input" ) ); - return( 0 ); - } - - /* - * A record can't be split across datagrams. If we need to read but - * are not at the beginning of a new record, the caller did something - * wrong. - */ - if( ssl->in_left != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - /* - * Don't even try to read if time's out already. - * This avoids by-passing the timer when repeatedly receiving messages - * that will end up being dropped. - */ - if( ssl_check_timer( ssl ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "timer has expired" ) ); - ret = MBEDTLS_ERR_SSL_TIMEOUT; - } - else - { - len = MBEDTLS_SSL_IN_BUFFER_LEN - ( ssl->in_hdr - ssl->in_buf ); - - if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) - timeout = ssl->handshake->retransmit_timeout; - else - timeout = ssl->conf->read_timeout; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "f_recv_timeout: %u ms", timeout ) ); - - if( ssl->f_recv_timeout != NULL ) - ret = ssl->f_recv_timeout( ssl->p_bio, ssl->in_hdr, len, - timeout ); - else - ret = ssl->f_recv( ssl->p_bio, ssl->in_hdr, len ); - - MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_recv(_timeout)", ret ); - - if( ret == 0 ) - return( MBEDTLS_ERR_SSL_CONN_EOF ); - } - - if( ret == MBEDTLS_ERR_SSL_TIMEOUT ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "timeout" ) ); - ssl_set_timer( ssl, 0 ); - - if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) - { - if( ssl_double_retransmit_timeout( ssl ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake timeout" ) ); - return( MBEDTLS_ERR_SSL_TIMEOUT ); - } - - if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend", ret ); - return( ret ); - } - - return( MBEDTLS_ERR_SSL_WANT_READ ); - } -#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION) - else if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && - ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ) - { - if( ( ret = ssl_resend_hello_request( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_resend_hello_request", ret ); - return( ret ); - } - - return( MBEDTLS_ERR_SSL_WANT_READ ); - } -#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */ - } - - if( ret < 0 ) - return( ret ); - - ssl->in_left = ret; - } - else -#endif - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d", - ssl->in_left, nb_want ) ); - - while( ssl->in_left < nb_want ) - { - len = nb_want - ssl->in_left; - - if( ssl_check_timer( ssl ) != 0 ) - ret = MBEDTLS_ERR_SSL_TIMEOUT; - else - { - if( ssl->f_recv_timeout != NULL ) - { - ret = ssl->f_recv_timeout( ssl->p_bio, - ssl->in_hdr + ssl->in_left, len, - ssl->conf->read_timeout ); - } - else - { - ret = ssl->f_recv( ssl->p_bio, - ssl->in_hdr + ssl->in_left, len ); - } - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d", - ssl->in_left, nb_want ) ); - MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_recv(_timeout)", ret ); - - if( ret == 0 ) - return( MBEDTLS_ERR_SSL_CONN_EOF ); - - if( ret < 0 ) - return( ret ); - - if ( (size_t)ret > len || ( INT_MAX > SIZE_MAX && ret > SIZE_MAX ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, - ( "f_recv returned %d bytes but only %lu were requested", - ret, (unsigned long)len ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - ssl->in_left += ret; - } - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= fetch input" ) ); - - return( 0 ); -} - -/* - * Flush any data not yet written - */ -int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl ) -{ - int ret; - unsigned char *buf; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> flush output" ) ); - - if( ssl->f_send == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() " - "or mbedtls_ssl_set_bio()" ) ); - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - /* Avoid incrementing counter if data is flushed */ - if( ssl->out_left == 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) ); - return( 0 ); - } - - while( ssl->out_left > 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "message length: %d, out_left: %d", - mbedtls_ssl_hdr_len( ssl ) + ssl->out_msglen, ssl->out_left ) ); - - buf = ssl->out_hdr - ssl->out_left; - ret = ssl->f_send( ssl->p_bio, buf, ssl->out_left ); - - MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", ret ); - - if( ret <= 0 ) - return( ret ); - - if( (size_t)ret > ssl->out_left || ( INT_MAX > SIZE_MAX && ret > SIZE_MAX ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, - ( "f_send returned %d bytes but only %lu bytes were sent", - ret, (unsigned long)ssl->out_left ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - ssl->out_left -= ret; - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - ssl->out_hdr = ssl->out_buf; - } - else -#endif - { - ssl->out_hdr = ssl->out_buf + 8; - } - ssl_update_out_pointers( ssl, ssl->transform_out ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) ); - - return( 0 ); -} - -/* - * Functions to handle the DTLS retransmission state machine - */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) -/* - * Append current handshake message to current outgoing flight - */ -static int ssl_flight_append( mbedtls_ssl_context *ssl ) -{ - mbedtls_ssl_flight_item *msg; - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_flight_append" ) ); - MBEDTLS_SSL_DEBUG_BUF( 4, "message appended to flight", - ssl->out_msg, ssl->out_msglen ); - - /* Allocate space for current message */ - if( ( msg = mbedtls_calloc( 1, sizeof( mbedtls_ssl_flight_item ) ) ) == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc %d bytes failed", - sizeof( mbedtls_ssl_flight_item ) ) ); - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - } - - if( ( msg->p = mbedtls_calloc( 1, ssl->out_msglen ) ) == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc %d bytes failed", ssl->out_msglen ) ); - mbedtls_free( msg ); - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - } - - /* Copy current handshake message with headers */ - memcpy( msg->p, ssl->out_msg, ssl->out_msglen ); - msg->len = ssl->out_msglen; - msg->type = ssl->out_msgtype; - msg->next = NULL; - - /* Append to the current flight */ - if( ssl->handshake->flight == NULL ) - ssl->handshake->flight = msg; - else - { - mbedtls_ssl_flight_item *cur = ssl->handshake->flight; - while( cur->next != NULL ) - cur = cur->next; - cur->next = msg; - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_flight_append" ) ); - return( 0 ); -} - -/* - * Free the current flight of handshake messages - */ -static void ssl_flight_free( mbedtls_ssl_flight_item *flight ) -{ - mbedtls_ssl_flight_item *cur = flight; - mbedtls_ssl_flight_item *next; - - while( cur != NULL ) - { - next = cur->next; - - mbedtls_free( cur->p ); - mbedtls_free( cur ); - - cur = next; - } -} - -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) -static void ssl_dtls_replay_reset( mbedtls_ssl_context *ssl ); -#endif - -/* - * Swap transform_out and out_ctr with the alternative ones - */ -static void ssl_swap_epochs( mbedtls_ssl_context *ssl ) -{ - mbedtls_ssl_transform *tmp_transform; - unsigned char tmp_out_ctr[8]; - - if( ssl->transform_out == ssl->handshake->alt_transform_out ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip swap epochs" ) ); - return; - } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "swap epochs" ) ); - - /* Swap transforms */ - tmp_transform = ssl->transform_out; - ssl->transform_out = ssl->handshake->alt_transform_out; - ssl->handshake->alt_transform_out = tmp_transform; - - /* Swap epoch + sequence_number */ - memcpy( tmp_out_ctr, ssl->cur_out_ctr, 8 ); - memcpy( ssl->cur_out_ctr, ssl->handshake->alt_out_ctr, 8 ); - memcpy( ssl->handshake->alt_out_ctr, tmp_out_ctr, 8 ); - - /* Adjust to the newly activated transform */ - ssl_update_out_pointers( ssl, ssl->transform_out ); - -#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) - if( mbedtls_ssl_hw_record_activate != NULL ) - { - if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_OUTBOUND ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret ); - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - } - } -#endif -} - -/* - * Retransmit the current flight of messages. - */ -int mbedtls_ssl_resend( mbedtls_ssl_context *ssl ) -{ - int ret = 0; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_resend" ) ); - - ret = mbedtls_ssl_flight_transmit( ssl ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_resend" ) ); - - return( ret ); -} - -/* - * Transmit or retransmit the current flight of messages. - * - * Need to remember the current message in case flush_output returns - * WANT_WRITE, causing us to exit this function and come back later. - * This function must be called until state is no longer SENDING. - */ -int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl ) -{ - int ret; - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_flight_transmit" ) ); - - if( ssl->handshake->retransmit_state != MBEDTLS_SSL_RETRANS_SENDING ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialise flight transmission" ) ); - - ssl->handshake->cur_msg = ssl->handshake->flight; - ssl->handshake->cur_msg_p = ssl->handshake->flight->p + 12; - ssl_swap_epochs( ssl ); - - ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_SENDING; - } - - while( ssl->handshake->cur_msg != NULL ) - { - size_t max_frag_len; - const mbedtls_ssl_flight_item * const cur = ssl->handshake->cur_msg; - - int const is_finished = - ( cur->type == MBEDTLS_SSL_MSG_HANDSHAKE && - cur->p[0] == MBEDTLS_SSL_HS_FINISHED ); - - uint8_t const force_flush = ssl->disable_datagram_packing == 1 ? - SSL_FORCE_FLUSH : SSL_DONT_FORCE_FLUSH; - - /* Swap epochs before sending Finished: we can't do it after - * sending ChangeCipherSpec, in case write returns WANT_READ. - * Must be done before copying, may change out_msg pointer */ - if( is_finished && ssl->handshake->cur_msg_p == ( cur->p + 12 ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "swap epochs to send finished message" ) ); - ssl_swap_epochs( ssl ); - } - - ret = ssl_get_remaining_payload_in_datagram( ssl ); - if( ret < 0 ) - return( ret ); - max_frag_len = (size_t) ret; - - /* CCS is copied as is, while HS messages may need fragmentation */ - if( cur->type == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC ) - { - if( max_frag_len == 0 ) - { - if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) - return( ret ); - - continue; - } - - memcpy( ssl->out_msg, cur->p, cur->len ); - ssl->out_msglen = cur->len; - ssl->out_msgtype = cur->type; - - /* Update position inside current message */ - ssl->handshake->cur_msg_p += cur->len; - } - else - { - const unsigned char * const p = ssl->handshake->cur_msg_p; - const size_t hs_len = cur->len - 12; - const size_t frag_off = p - ( cur->p + 12 ); - const size_t rem_len = hs_len - frag_off; - size_t cur_hs_frag_len, max_hs_frag_len; - - if( ( max_frag_len < 12 ) || ( max_frag_len == 12 && hs_len != 0 ) ) - { - if( is_finished ) - ssl_swap_epochs( ssl ); - - if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) - return( ret ); - - continue; - } - max_hs_frag_len = max_frag_len - 12; - - cur_hs_frag_len = rem_len > max_hs_frag_len ? - max_hs_frag_len : rem_len; - - if( frag_off == 0 && cur_hs_frag_len != hs_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "fragmenting handshake message (%u > %u)", - (unsigned) cur_hs_frag_len, - (unsigned) max_hs_frag_len ) ); - } - - /* Messages are stored with handshake headers as if not fragmented, - * copy beginning of headers then fill fragmentation fields. - * Handshake headers: type(1) len(3) seq(2) f_off(3) f_len(3) */ - memcpy( ssl->out_msg, cur->p, 6 ); - - ssl->out_msg[6] = ( ( frag_off >> 16 ) & 0xff ); - ssl->out_msg[7] = ( ( frag_off >> 8 ) & 0xff ); - ssl->out_msg[8] = ( ( frag_off ) & 0xff ); - - ssl->out_msg[ 9] = ( ( cur_hs_frag_len >> 16 ) & 0xff ); - ssl->out_msg[10] = ( ( cur_hs_frag_len >> 8 ) & 0xff ); - ssl->out_msg[11] = ( ( cur_hs_frag_len ) & 0xff ); - - MBEDTLS_SSL_DEBUG_BUF( 3, "handshake header", ssl->out_msg, 12 ); - - /* Copy the handshake message content and set records fields */ - memcpy( ssl->out_msg + 12, p, cur_hs_frag_len ); - ssl->out_msglen = cur_hs_frag_len + 12; - ssl->out_msgtype = cur->type; - - /* Update position inside current message */ - ssl->handshake->cur_msg_p += cur_hs_frag_len; - } - - /* If done with the current message move to the next one if any */ - if( ssl->handshake->cur_msg_p >= cur->p + cur->len ) - { - if( cur->next != NULL ) - { - ssl->handshake->cur_msg = cur->next; - ssl->handshake->cur_msg_p = cur->next->p + 12; - } - else - { - ssl->handshake->cur_msg = NULL; - ssl->handshake->cur_msg_p = NULL; - } - } - - /* Actually send the message out */ - if( ( ret = mbedtls_ssl_write_record( ssl, force_flush ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); - return( ret ); - } - } - - if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) - return( ret ); - - /* Update state and set timer */ - if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) - ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED; - else - { - ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING; - ssl_set_timer( ssl, ssl->handshake->retransmit_timeout ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_flight_transmit" ) ); - - return( 0 ); -} - -/* - * To be called when the last message of an incoming flight is received. - */ -void mbedtls_ssl_recv_flight_completed( mbedtls_ssl_context *ssl ) -{ - /* We won't need to resend that one any more */ - ssl_flight_free( ssl->handshake->flight ); - ssl->handshake->flight = NULL; - ssl->handshake->cur_msg = NULL; - - /* The next incoming flight will start with this msg_seq */ - ssl->handshake->in_flight_start_seq = ssl->handshake->in_msg_seq; - - /* We don't want to remember CCS's across flight boundaries. */ - ssl->handshake->buffering.seen_ccs = 0; - - /* Clear future message buffering structure. */ - ssl_buffering_free( ssl ); - - /* Cancel timer */ - ssl_set_timer( ssl, 0 ); - - if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && - ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED ) - { - ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED; - } - else - ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING; -} - -/* - * To be called when the last message of an outgoing flight is send. - */ -void mbedtls_ssl_send_flight_completed( mbedtls_ssl_context *ssl ) -{ - ssl_reset_retransmit_timeout( ssl ); - ssl_set_timer( ssl, ssl->handshake->retransmit_timeout ); - - if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && - ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED ) - { - ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED; - } - else - ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING; -} -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -/* - * Handshake layer functions - */ - -/* - * Write (DTLS: or queue) current handshake (including CCS) message. - * - * - fill in handshake headers - * - update handshake checksum - * - DTLS: save message for resending - * - then pass to the record layer - * - * DTLS: except for HelloRequest, messages are only queued, and will only be - * actually sent when calling flight_transmit() or resend(). - * - * Inputs: - * - ssl->out_msglen: 4 + actual handshake message len - * (4 is the size of handshake headers for TLS) - * - ssl->out_msg[0]: the handshake type (ClientHello, ServerHello, etc) - * - ssl->out_msg + 4: the handshake message body - * - * Outputs, ie state before passing to flight_append() or write_record(): - * - ssl->out_msglen: the length of the record contents - * (including handshake headers but excluding record headers) - * - ssl->out_msg: the record contents (handshake headers + content) - */ -int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl ) -{ - int ret; - const size_t hs_len = ssl->out_msglen - 4; - const unsigned char hs_type = ssl->out_msg[0]; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write handshake message" ) ); - - /* - * Sanity checks - */ - if( ssl->out_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE && - ssl->out_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC ) - { - /* In SSLv3, the client might send a NoCertificate alert. */ -#if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_CLI_C) - if( ! ( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 && - ssl->out_msgtype == MBEDTLS_SSL_MSG_ALERT && - ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) ) -#endif /* MBEDTLS_SSL_PROTO_SSL3 && MBEDTLS_SSL_SRV_C */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - } - - /* Whenever we send anything different from a - * HelloRequest we should be in a handshake - double check. */ - if( ! ( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && - hs_type == MBEDTLS_SSL_HS_HELLO_REQUEST ) && - ssl->handshake == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl->handshake != NULL && - ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } -#endif - - /* Double-check that we did not exceed the bounds - * of the outgoing record buffer. - * This should never fail as the various message - * writing functions must obey the bounds of the - * outgoing record buffer, but better be safe. - * - * Note: We deliberately do not check for the MTU or MFL here. - */ - if( ssl->out_msglen > MBEDTLS_SSL_OUT_CONTENT_LEN ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "Record too large: " - "size %u, maximum %u", - (unsigned) ssl->out_msglen, - (unsigned) MBEDTLS_SSL_OUT_CONTENT_LEN ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - /* - * Fill handshake headers - */ - if( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE ) - { - ssl->out_msg[1] = (unsigned char)( hs_len >> 16 ); - ssl->out_msg[2] = (unsigned char)( hs_len >> 8 ); - ssl->out_msg[3] = (unsigned char)( hs_len ); - - /* - * DTLS has additional fields in the Handshake layer, - * between the length field and the actual payload: - * uint16 message_seq; - * uint24 fragment_offset; - * uint24 fragment_length; - */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - /* Make room for the additional DTLS fields */ - if( MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen < 8 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS handshake message too large: " - "size %u, maximum %u", - (unsigned) ( hs_len ), - (unsigned) ( MBEDTLS_SSL_OUT_CONTENT_LEN - 12 ) ) ); - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - memmove( ssl->out_msg + 12, ssl->out_msg + 4, hs_len ); - ssl->out_msglen += 8; - - /* Write message_seq and update it, except for HelloRequest */ - if( hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST ) - { - ssl->out_msg[4] = ( ssl->handshake->out_msg_seq >> 8 ) & 0xFF; - ssl->out_msg[5] = ( ssl->handshake->out_msg_seq ) & 0xFF; - ++( ssl->handshake->out_msg_seq ); - } - else - { - ssl->out_msg[4] = 0; - ssl->out_msg[5] = 0; - } - - /* Handshake hashes are computed without fragmentation, - * so set frag_offset = 0 and frag_len = hs_len for now */ - memset( ssl->out_msg + 6, 0x00, 3 ); - memcpy( ssl->out_msg + 9, ssl->out_msg + 1, 3 ); - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - /* Update running hashes of handshake messages seen */ - if( hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST ) - ssl->handshake->update_checksum( ssl, ssl->out_msg, ssl->out_msglen ); - } - - /* Either send now, or just save to be sent (and resent) later */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ! ( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && - hs_type == MBEDTLS_SSL_HS_HELLO_REQUEST ) ) - { - if( ( ret = ssl_flight_append( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_flight_append", ret ); - return( ret ); - } - } - else -#endif - { - if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_record", ret ); - return( ret ); - } - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write handshake message" ) ); - - return( 0 ); -} - -/* - * Record layer functions - */ - -/* - * Write current record. - * - * Uses: - * - ssl->out_msgtype: type of the message (AppData, Handshake, Alert, CCS) - * - ssl->out_msglen: length of the record content (excl headers) - * - ssl->out_msg: record content - */ -int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush ) -{ - int ret, done = 0; - size_t len = ssl->out_msglen; - uint8_t flush = force_flush; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write record" ) ); - -#if defined(MBEDTLS_ZLIB_SUPPORT) - if( ssl->transform_out != NULL && - ssl->session_out->compression == MBEDTLS_SSL_COMPRESS_DEFLATE ) - { - if( ( ret = ssl_compress_buf( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_compress_buf", ret ); - return( ret ); - } - - len = ssl->out_msglen; - } -#endif /*MBEDTLS_ZLIB_SUPPORT */ - -#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) - if( mbedtls_ssl_hw_record_write != NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_write()" ) ); - - ret = mbedtls_ssl_hw_record_write( ssl ); - if( ret != 0 && ret != MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_write", ret ); - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - } - - if( ret == 0 ) - done = 1; - } -#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ - if( !done ) - { - unsigned i; - size_t protected_record_size; - - ssl->out_hdr[0] = (unsigned char) ssl->out_msgtype; - mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver, - ssl->conf->transport, ssl->out_hdr + 1 ); - - memcpy( ssl->out_ctr, ssl->cur_out_ctr, 8 ); - ssl->out_len[0] = (unsigned char)( len >> 8 ); - ssl->out_len[1] = (unsigned char)( len ); - - if( ssl->transform_out != NULL ) - { - if( ( ret = ssl_encrypt_buf( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_encrypt_buf", ret ); - return( ret ); - } - - len = ssl->out_msglen; - ssl->out_len[0] = (unsigned char)( len >> 8 ); - ssl->out_len[1] = (unsigned char)( len ); - } - - protected_record_size = len + mbedtls_ssl_hdr_len( ssl ); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - /* In case of DTLS, double-check that we don't exceed - * the remaining space in the datagram. */ - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - ret = ssl_get_remaining_space_in_datagram( ssl ); - if( ret < 0 ) - return( ret ); - - if( protected_record_size > (size_t) ret ) - { - /* Should never happen */ - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "output record: msgtype = %d, " - "version = [%d:%d], msglen = %d", - ssl->out_hdr[0], ssl->out_hdr[1], - ssl->out_hdr[2], len ) ); - - MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network", - ssl->out_hdr, protected_record_size ); - - ssl->out_left += protected_record_size; - ssl->out_hdr += protected_record_size; - ssl_update_out_pointers( ssl, ssl->transform_out ); - - for( i = 8; i > ssl_ep_len( ssl ); i-- ) - if( ++ssl->cur_out_ctr[i - 1] != 0 ) - break; - - /* The loop goes to its end iff the counter is wrapping */ - if( i == ssl_ep_len( ssl ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "outgoing message counter would wrap" ) ); - return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING ); - } - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - flush == SSL_DONT_FORCE_FLUSH ) - { - size_t remaining; - ret = ssl_get_remaining_payload_in_datagram( ssl ); - if( ret < 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_get_remaining_payload_in_datagram", - ret ); - return( ret ); - } - - remaining = (size_t) ret; - if( remaining == 0 ) - { - flush = SSL_FORCE_FLUSH; - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Still %u bytes available in current datagram", (unsigned) remaining ) ); - } - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - if( ( flush == SSL_FORCE_FLUSH ) && - ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret ); - return( ret ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write record" ) ); - - return( 0 ); -} - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - -static int ssl_hs_is_proper_fragment( mbedtls_ssl_context *ssl ) -{ - if( ssl->in_msglen < ssl->in_hslen || - memcmp( ssl->in_msg + 6, "\0\0\0", 3 ) != 0 || - memcmp( ssl->in_msg + 9, ssl->in_msg + 1, 3 ) != 0 ) - { - return( 1 ); - } - return( 0 ); -} - -static uint32_t ssl_get_hs_frag_len( mbedtls_ssl_context const *ssl ) -{ - return( ( ssl->in_msg[9] << 16 ) | - ( ssl->in_msg[10] << 8 ) | - ssl->in_msg[11] ); -} - -static uint32_t ssl_get_hs_frag_off( mbedtls_ssl_context const *ssl ) -{ - return( ( ssl->in_msg[6] << 16 ) | - ( ssl->in_msg[7] << 8 ) | - ssl->in_msg[8] ); -} - -static int ssl_check_hs_header( mbedtls_ssl_context const *ssl ) -{ - uint32_t msg_len, frag_off, frag_len; - - msg_len = ssl_get_hs_total_len( ssl ); - frag_off = ssl_get_hs_frag_off( ssl ); - frag_len = ssl_get_hs_frag_len( ssl ); - - if( frag_off > msg_len ) - return( -1 ); - - if( frag_len > msg_len - frag_off ) - return( -1 ); - - if( frag_len + 12 > ssl->in_msglen ) - return( -1 ); - - return( 0 ); -} - -/* - * Mark bits in bitmask (used for DTLS HS reassembly) - */ -static void ssl_bitmask_set( unsigned char *mask, size_t offset, size_t len ) -{ - unsigned int start_bits, end_bits; - - start_bits = 8 - ( offset % 8 ); - if( start_bits != 8 ) - { - size_t first_byte_idx = offset / 8; - - /* Special case */ - if( len <= start_bits ) - { - for( ; len != 0; len-- ) - mask[first_byte_idx] |= 1 << ( start_bits - len ); - - /* Avoid potential issues with offset or len becoming invalid */ - return; - } - - offset += start_bits; /* Now offset % 8 == 0 */ - len -= start_bits; - - for( ; start_bits != 0; start_bits-- ) - mask[first_byte_idx] |= 1 << ( start_bits - 1 ); - } - - end_bits = len % 8; - if( end_bits != 0 ) - { - size_t last_byte_idx = ( offset + len ) / 8; - - len -= end_bits; /* Now len % 8 == 0 */ - - for( ; end_bits != 0; end_bits-- ) - mask[last_byte_idx] |= 1 << ( 8 - end_bits ); - } - - memset( mask + offset / 8, 0xFF, len / 8 ); -} - -/* - * Check that bitmask is full - */ -static int ssl_bitmask_check( unsigned char *mask, size_t len ) -{ - size_t i; - - for( i = 0; i < len / 8; i++ ) - if( mask[i] != 0xFF ) - return( -1 ); - - for( i = 0; i < len % 8; i++ ) - if( ( mask[len / 8] & ( 1 << ( 7 - i ) ) ) == 0 ) - return( -1 ); - - return( 0 ); -} - -/* msg_len does not include the handshake header */ -static size_t ssl_get_reassembly_buffer_size( size_t msg_len, - unsigned add_bitmap ) -{ - size_t alloc_len; - - alloc_len = 12; /* Handshake header */ - alloc_len += msg_len; /* Content buffer */ - - if( add_bitmap ) - alloc_len += msg_len / 8 + ( msg_len % 8 != 0 ); /* Bitmap */ - - return( alloc_len ); -} - -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -static uint32_t ssl_get_hs_total_len( mbedtls_ssl_context const *ssl ) -{ - return( ( ssl->in_msg[1] << 16 ) | - ( ssl->in_msg[2] << 8 ) | - ssl->in_msg[3] ); -} - -int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl ) -{ - if( ssl->in_msglen < mbedtls_ssl_hs_hdr_len( ssl ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake message too short: %d", - ssl->in_msglen ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } - - ssl->in_hslen = mbedtls_ssl_hs_hdr_len( ssl ) + ssl_get_hs_total_len( ssl ); - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "handshake message: msglen =" - " %d, type = %d, hslen = %d", - ssl->in_msglen, ssl->in_msg[0], ssl->in_hslen ) ); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - int ret; - unsigned int recv_msg_seq = ( ssl->in_msg[4] << 8 ) | ssl->in_msg[5]; - - if( ssl_check_hs_header( ssl ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid handshake header" ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } - - if( ssl->handshake != NULL && - ( ( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER && - recv_msg_seq != ssl->handshake->in_msg_seq ) || - ( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER && - ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO ) ) ) - { - if( recv_msg_seq > ssl->handshake->in_msg_seq ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "received future handshake message of sequence number %u (next %u)", - recv_msg_seq, - ssl->handshake->in_msg_seq ) ); - return( MBEDTLS_ERR_SSL_EARLY_MESSAGE ); - } - - /* Retransmit only on last message from previous flight, to avoid - * too many retransmissions. - * Besides, No sane server ever retransmits HelloVerifyRequest */ - if( recv_msg_seq == ssl->handshake->in_flight_start_seq - 1 && - ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "received message from last flight, " - "message_seq = %d, start_of_flight = %d", - recv_msg_seq, - ssl->handshake->in_flight_start_seq ) ); - - if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend", ret ); - return( ret ); - } - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "dropping out-of-sequence message: " - "message_seq = %d, expected = %d", - recv_msg_seq, - ssl->handshake->in_msg_seq ) ); - } - - return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING ); - } - /* Wait until message completion to increment in_msg_seq */ - - /* Message reassembly is handled alongside buffering of future - * messages; the commonality is that both handshake fragments and - * future messages cannot be forwarded immediately to the - * handshake logic layer. */ - if( ssl_hs_is_proper_fragment( ssl ) == 1 ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "found fragmented DTLS handshake message" ) ); - return( MBEDTLS_ERR_SSL_EARLY_MESSAGE ); - } - } - else -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - /* With TLS we don't handle fragmentation (for now) */ - if( ssl->in_msglen < ssl->in_hslen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLS handshake fragmentation not supported" ) ); - return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); - } - - return( 0 ); -} - -void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl ) -{ - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - - if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER && hs != NULL ) - { - ssl->handshake->update_checksum( ssl, ssl->in_msg, ssl->in_hslen ); - } - - /* Handshake message is complete, increment counter */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl->handshake != NULL ) - { - unsigned offset; - mbedtls_ssl_hs_buffer *hs_buf; - - /* Increment handshake sequence number */ - hs->in_msg_seq++; - - /* - * Clear up handshake buffering and reassembly structure. - */ - - /* Free first entry */ - ssl_buffering_free_slot( ssl, 0 ); - - /* Shift all other entries */ - for( offset = 0, hs_buf = &hs->buffering.hs[0]; - offset + 1 < MBEDTLS_SSL_MAX_BUFFERED_HS; - offset++, hs_buf++ ) - { - *hs_buf = *(hs_buf + 1); - } - - /* Create a fresh last entry */ - memset( hs_buf, 0, sizeof( mbedtls_ssl_hs_buffer ) ); - } -#endif -} - -/* - * DTLS anti-replay: RFC 6347 4.1.2.6 - * - * in_window is a field of bits numbered from 0 (lsb) to 63 (msb). - * Bit n is set iff record number in_window_top - n has been seen. - * - * Usually, in_window_top is the last record number seen and the lsb of - * in_window is set. The only exception is the initial state (record number 0 - * not seen yet). - */ -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) -static void ssl_dtls_replay_reset( mbedtls_ssl_context *ssl ) -{ - ssl->in_window_top = 0; - ssl->in_window = 0; -} - -static inline uint64_t ssl_load_six_bytes( unsigned char *buf ) -{ - return( ( (uint64_t) buf[0] << 40 ) | - ( (uint64_t) buf[1] << 32 ) | - ( (uint64_t) buf[2] << 24 ) | - ( (uint64_t) buf[3] << 16 ) | - ( (uint64_t) buf[4] << 8 ) | - ( (uint64_t) buf[5] ) ); -} - -/* - * Return 0 if sequence number is acceptable, -1 otherwise - */ -int mbedtls_ssl_dtls_replay_check( mbedtls_ssl_context *ssl ) -{ - uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 ); - uint64_t bit; - - if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED ) - return( 0 ); - - if( rec_seqnum > ssl->in_window_top ) - return( 0 ); - - bit = ssl->in_window_top - rec_seqnum; - - if( bit >= 64 ) - return( -1 ); - - if( ( ssl->in_window & ( (uint64_t) 1 << bit ) ) != 0 ) - return( -1 ); - - return( 0 ); -} - -/* - * Update replay window on new validated record - */ -void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl ) -{ - uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 ); - - if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED ) - return; - - if( rec_seqnum > ssl->in_window_top ) - { - /* Update window_top and the contents of the window */ - uint64_t shift = rec_seqnum - ssl->in_window_top; - - if( shift >= 64 ) - ssl->in_window = 1; - else - { - ssl->in_window <<= shift; - ssl->in_window |= 1; - } - - ssl->in_window_top = rec_seqnum; - } - else - { - /* Mark that number as seen in the current window */ - uint64_t bit = ssl->in_window_top - rec_seqnum; - - if( bit < 64 ) /* Always true, but be extra sure */ - ssl->in_window |= (uint64_t) 1 << bit; - } -} -#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ - -#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C) -/* Forward declaration */ -static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial ); - -/* - * Without any SSL context, check if a datagram looks like a ClientHello with - * a valid cookie, and if it doesn't, generate a HelloVerifyRequest message. - * Both input and output include full DTLS headers. - * - * - if cookie is valid, return 0 - * - if ClientHello looks superficially valid but cookie is not, - * fill obuf and set olen, then - * return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED - * - otherwise return a specific error code - */ -static int ssl_check_dtls_clihlo_cookie( - mbedtls_ssl_cookie_write_t *f_cookie_write, - mbedtls_ssl_cookie_check_t *f_cookie_check, - void *p_cookie, - const unsigned char *cli_id, size_t cli_id_len, - const unsigned char *in, size_t in_len, - unsigned char *obuf, size_t buf_len, size_t *olen ) -{ - size_t sid_len, cookie_len; - unsigned char *p; - - if( f_cookie_write == NULL || f_cookie_check == NULL ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - /* - * Structure of ClientHello with record and handshake headers, - * and expected values. We don't need to check a lot, more checks will be - * done when actually parsing the ClientHello - skipping those checks - * avoids code duplication and does not make cookie forging any easier. - * - * 0-0 ContentType type; copied, must be handshake - * 1-2 ProtocolVersion version; copied - * 3-4 uint16 epoch; copied, must be 0 - * 5-10 uint48 sequence_number; copied - * 11-12 uint16 length; (ignored) - * - * 13-13 HandshakeType msg_type; (ignored) - * 14-16 uint24 length; (ignored) - * 17-18 uint16 message_seq; copied - * 19-21 uint24 fragment_offset; copied, must be 0 - * 22-24 uint24 fragment_length; (ignored) - * - * 25-26 ProtocolVersion client_version; (ignored) - * 27-58 Random random; (ignored) - * 59-xx SessionID session_id; 1 byte len + sid_len content - * 60+ opaque cookie<0..2^8-1>; 1 byte len + content - * ... - * - * Minimum length is 61 bytes. - */ - if( in_len < 61 || - in[0] != MBEDTLS_SSL_MSG_HANDSHAKE || - in[3] != 0 || in[4] != 0 || - in[19] != 0 || in[20] != 0 || in[21] != 0 ) - { - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - - sid_len = in[59]; - if( sid_len > in_len - 61 ) - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - - cookie_len = in[60 + sid_len]; - if( cookie_len > in_len - 60 ) - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - - if( f_cookie_check( p_cookie, in + sid_len + 61, cookie_len, - cli_id, cli_id_len ) == 0 ) - { - /* Valid cookie */ - return( 0 ); - } - - /* - * If we get here, we've got an invalid cookie, let's prepare HVR. - * - * 0-0 ContentType type; copied - * 1-2 ProtocolVersion version; copied - * 3-4 uint16 epoch; copied - * 5-10 uint48 sequence_number; copied - * 11-12 uint16 length; olen - 13 - * - * 13-13 HandshakeType msg_type; hello_verify_request - * 14-16 uint24 length; olen - 25 - * 17-18 uint16 message_seq; copied - * 19-21 uint24 fragment_offset; copied - * 22-24 uint24 fragment_length; olen - 25 - * - * 25-26 ProtocolVersion server_version; 0xfe 0xff - * 27-27 opaque cookie<0..2^8-1>; cookie_len = olen - 27, cookie - * - * Minimum length is 28. - */ - if( buf_len < 28 ) - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); - - /* Copy most fields and adapt others */ - memcpy( obuf, in, 25 ); - obuf[13] = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST; - obuf[25] = 0xfe; - obuf[26] = 0xff; - - /* Generate and write actual cookie */ - p = obuf + 28; - if( f_cookie_write( p_cookie, - &p, obuf + buf_len, cli_id, cli_id_len ) != 0 ) - { - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - *olen = p - obuf; - - /* Go back and fill length fields */ - obuf[27] = (unsigned char)( *olen - 28 ); - - obuf[14] = obuf[22] = (unsigned char)( ( *olen - 25 ) >> 16 ); - obuf[15] = obuf[23] = (unsigned char)( ( *olen - 25 ) >> 8 ); - obuf[16] = obuf[24] = (unsigned char)( ( *olen - 25 ) ); - - obuf[11] = (unsigned char)( ( *olen - 13 ) >> 8 ); - obuf[12] = (unsigned char)( ( *olen - 13 ) ); - - return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED ); -} - -/* - * Handle possible client reconnect with the same UDP quadruplet - * (RFC 6347 Section 4.2.8). - * - * Called by ssl_parse_record_header() in case we receive an epoch 0 record - * that looks like a ClientHello. - * - * - if the input looks like a ClientHello without cookies, - * send back HelloVerifyRequest, then - * return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED - * - if the input looks like a ClientHello with a valid cookie, - * reset the session of the current context, and - * return MBEDTLS_ERR_SSL_CLIENT_RECONNECT - * - if anything goes wrong, return a specific error code - * - * mbedtls_ssl_read_record() will ignore the record if anything else than - * MBEDTLS_ERR_SSL_CLIENT_RECONNECT or 0 is returned, although this function - * cannot not return 0. - */ -static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl ) -{ - int ret; - size_t len; - - ret = ssl_check_dtls_clihlo_cookie( - ssl->conf->f_cookie_write, - ssl->conf->f_cookie_check, - ssl->conf->p_cookie, - ssl->cli_id, ssl->cli_id_len, - ssl->in_buf, ssl->in_left, - ssl->out_buf, MBEDTLS_SSL_OUT_CONTENT_LEN, &len ); - - MBEDTLS_SSL_DEBUG_RET( 2, "ssl_check_dtls_clihlo_cookie", ret ); - - if( ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED ) - { - /* Don't check write errors as we can't do anything here. - * If the error is permanent we'll catch it later, - * if it's not, then hopefully it'll work next time. */ - (void) ssl->f_send( ssl->p_bio, ssl->out_buf, len ); - - return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED ); - } - - if( ret == 0 ) - { - /* Got a valid cookie, partially reset context */ - if( ( ret = ssl_session_reset_int( ssl, 1 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "reset", ret ); - return( ret ); - } - - return( MBEDTLS_ERR_SSL_CLIENT_RECONNECT ); - } - - return( ret ); -} -#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */ - -/* - * ContentType type; - * ProtocolVersion version; - * uint16 epoch; // DTLS only - * uint48 sequence_number; // DTLS only - * uint16 length; - * - * Return 0 if header looks sane (and, for DTLS, the record is expected) - * MBEDTLS_ERR_SSL_INVALID_RECORD if the header looks bad, - * MBEDTLS_ERR_SSL_UNEXPECTED_RECORD (DTLS only) if sane but unexpected. - * - * With DTLS, mbedtls_ssl_read_record() will: - * 1. proceed with the record if this function returns 0 - * 2. drop only the current record if this function returns UNEXPECTED_RECORD - * 3. return CLIENT_RECONNECT if this function return that value - * 4. drop the whole datagram if this function returns anything else. - * Point 2 is needed when the peer is resending, and we have already received - * the first record from a datagram but are still waiting for the others. - */ -static int ssl_parse_record_header( mbedtls_ssl_context *ssl ) -{ - int major_ver, minor_ver; - - MBEDTLS_SSL_DEBUG_BUF( 4, "input record header", ssl->in_hdr, mbedtls_ssl_hdr_len( ssl ) ); - - ssl->in_msgtype = ssl->in_hdr[0]; - ssl->in_msglen = ( ssl->in_len[0] << 8 ) | ssl->in_len[1]; - mbedtls_ssl_read_version( &major_ver, &minor_ver, ssl->conf->transport, ssl->in_hdr + 1 ); - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "input record: msgtype = %d, " - "version = [%d:%d], msglen = %d", - ssl->in_msgtype, - major_ver, minor_ver, ssl->in_msglen ) ); - - /* Check record type */ - if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE && - ssl->in_msgtype != MBEDTLS_SSL_MSG_ALERT && - ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC && - ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "unknown record type" ) ); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - /* Silently ignore invalid DTLS records as recommended by RFC 6347 - * Section 4.1.2.7 */ - if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); - - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } - - /* Check version */ - if( major_ver != ssl->major_ver ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "major version mismatch" ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } - - if( minor_ver > ssl->conf->max_minor_ver ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "minor version mismatch" ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } - - /* Check length against the size of our buffer */ - if( ssl->in_msglen > MBEDTLS_SSL_IN_BUFFER_LEN - - (size_t)( ssl->in_msg - ssl->in_buf ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } - - /* - * DTLS-related tests. - * Check epoch before checking length constraint because - * the latter varies with the epoch. E.g., if a ChangeCipherSpec - * message gets duplicated before the corresponding Finished message, - * the second ChangeCipherSpec should be discarded because it belongs - * to an old epoch, but not because its length is shorter than - * the minimum record length for packets using the new record transform. - * Note that these two kinds of failures are handled differently, - * as an unexpected record is silently skipped but an invalid - * record leads to the entire datagram being dropped. - */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - unsigned int rec_epoch = ( ssl->in_ctr[0] << 8 ) | ssl->in_ctr[1]; - - /* Check epoch (and sequence number) with DTLS */ - if( rec_epoch != ssl->in_epoch ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "record from another epoch: " - "expected %d, received %d", - ssl->in_epoch, rec_epoch ) ); - -#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C) - /* - * Check for an epoch 0 ClientHello. We can't use in_msg here to - * access the first byte of record content (handshake type), as we - * have an active transform (possibly iv_len != 0), so use the - * fact that the record header len is 13 instead. - */ - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && - ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER && - rec_epoch == 0 && - ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && - ssl->in_left > 13 && - ssl->in_buf[13] == MBEDTLS_SSL_HS_CLIENT_HELLO ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "possible client reconnect " - "from the same port" ) ); - return( ssl_handle_possible_reconnect( ssl ) ); - } - else -#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */ - { - /* Consider buffering the record. */ - if( rec_epoch == (unsigned int) ssl->in_epoch + 1 ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Consider record for buffering" ) ); - return( MBEDTLS_ERR_SSL_EARLY_MESSAGE ); - } - - return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ); - } - } - -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) - /* Replay detection only works for the current epoch */ - if( rec_epoch == ssl->in_epoch && - mbedtls_ssl_dtls_replay_check( ssl ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "replayed record" ) ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ); - } -#endif - - /* Drop unexpected ApplicationData records, - * except at the beginning of renegotiations */ - if( ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA && - ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER -#if defined(MBEDTLS_SSL_RENEGOTIATION) - && ! ( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && - ssl->state == MBEDTLS_SSL_SERVER_HELLO ) -#endif - ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping unexpected ApplicationData" ) ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ); - } - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - - /* Check length against bounds of the current transform and version */ - if( ssl->transform_in == NULL ) - { - if( ssl->in_msglen < 1 || - ssl->in_msglen > MBEDTLS_SSL_IN_CONTENT_LEN ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } - } - else - { - if( ssl->in_msglen < ssl->transform_in->minlen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } - -#if defined(MBEDTLS_SSL_PROTO_SSL3) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 && - ssl->in_msglen > ssl->transform_in->minlen + MBEDTLS_SSL_IN_CONTENT_LEN ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) - /* - * TLS encrypted messages can have up to 256 bytes of padding - */ - if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 && - ssl->in_msglen > ssl->transform_in->minlen + - MBEDTLS_SSL_IN_CONTENT_LEN + 256 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } -#endif - } - - return( 0 ); -} - -/* - * If applicable, decrypt (and decompress) record content - */ -static int ssl_prepare_record_content( mbedtls_ssl_context *ssl ) -{ - int ret, done = 0; - - MBEDTLS_SSL_DEBUG_BUF( 4, "input record from network", - ssl->in_hdr, mbedtls_ssl_hdr_len( ssl ) + ssl->in_msglen ); - -#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) - if( mbedtls_ssl_hw_record_read != NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_read()" ) ); - - ret = mbedtls_ssl_hw_record_read( ssl ); - if( ret != 0 && ret != MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_read", ret ); - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - } - - if( ret == 0 ) - done = 1; - } -#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ - if( !done && ssl->transform_in != NULL ) - { - if( ( ret = ssl_decrypt_buf( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decrypt_buf", ret ); - return( ret ); - } - - MBEDTLS_SSL_DEBUG_BUF( 4, "input payload after decrypt", - ssl->in_msg, ssl->in_msglen ); - - if( ssl->in_msglen > MBEDTLS_SSL_IN_CONTENT_LEN ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } - } - -#if defined(MBEDTLS_ZLIB_SUPPORT) - if( ssl->transform_in != NULL && - ssl->session_in->compression == MBEDTLS_SSL_COMPRESS_DEFLATE ) - { - if( ( ret = ssl_decompress_buf( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decompress_buf", ret ); - return( ret ); - } - } -#endif /* MBEDTLS_ZLIB_SUPPORT */ - -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - mbedtls_ssl_dtls_replay_update( ssl ); - } -#endif - - return( 0 ); -} - -static void ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl ); - -/* - * Read a record. - * - * Silently ignore non-fatal alert (and for DTLS, invalid records as well, - * RFC 6347 4.1.2.7) and continue reading until a valid record is found. - * - */ - -/* Helper functions for mbedtls_ssl_read_record(). */ -static int ssl_consume_current_message( mbedtls_ssl_context *ssl ); -static int ssl_get_next_record( mbedtls_ssl_context *ssl ); -static int ssl_record_is_in_progress( mbedtls_ssl_context *ssl ); - -int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl, - unsigned update_hs_digest ) -{ - int ret; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read record" ) ); - - if( ssl->keep_current_message == 0 ) - { - do { - - ret = ssl_consume_current_message( ssl ); - if( ret != 0 ) - return( ret ); - - if( ssl_record_is_in_progress( ssl ) == 0 ) - { -#if defined(MBEDTLS_SSL_PROTO_DTLS) - int have_buffered = 0; - - /* We only check for buffered messages if the - * current datagram is fully consumed. */ - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl_next_record_is_in_datagram( ssl ) == 0 ) - { - if( ssl_load_buffered_message( ssl ) == 0 ) - have_buffered = 1; - } - - if( have_buffered == 0 ) -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - { - ret = ssl_get_next_record( ssl ); - if( ret == MBEDTLS_ERR_SSL_CONTINUE_PROCESSING ) - continue; - - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_get_next_record" ), ret ); - return( ret ); - } - } - } - - ret = mbedtls_ssl_handle_message_type( ssl ); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE ) - { - /* Buffer future message */ - ret = ssl_buffer_message( ssl ); - if( ret != 0 ) - return( ret ); - - ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING; - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - } while( MBEDTLS_ERR_SSL_NON_FATAL == ret || - MBEDTLS_ERR_SSL_CONTINUE_PROCESSING == ret ); - - if( 0 != ret ) - { - MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_handle_message_type" ), ret ); - return( ret ); - } - - if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && - update_hs_digest == 1 ) - { - mbedtls_ssl_update_handshake_status( ssl ); - } - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "reuse previously read message" ) ); - ssl->keep_current_message = 0; - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read record" ) ); - - return( 0 ); -} - -#if defined(MBEDTLS_SSL_PROTO_DTLS) -static int ssl_next_record_is_in_datagram( mbedtls_ssl_context *ssl ) -{ - if( ssl->in_left > ssl->next_record_offset ) - return( 1 ); - - return( 0 ); -} - -static int ssl_load_buffered_message( mbedtls_ssl_context *ssl ) -{ - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - mbedtls_ssl_hs_buffer * hs_buf; - int ret = 0; - - if( hs == NULL ) - return( -1 ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_load_buffered_messsage" ) ); - - if( ssl->state == MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC || - ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC ) - { - /* Check if we have seen a ChangeCipherSpec before. - * If yes, synthesize a CCS record. */ - if( !hs->buffering.seen_ccs ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "CCS not seen in the current flight" ) ); - ret = -1; - goto exit; - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Injecting buffered CCS message" ) ); - ssl->in_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC; - ssl->in_msglen = 1; - ssl->in_msg[0] = 1; - - /* As long as they are equal, the exact value doesn't matter. */ - ssl->in_left = 0; - ssl->next_record_offset = 0; - - hs->buffering.seen_ccs = 0; - goto exit; - } - -#if defined(MBEDTLS_DEBUG_C) - /* Debug only */ - { - unsigned offset; - for( offset = 1; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++ ) - { - hs_buf = &hs->buffering.hs[offset]; - if( hs_buf->is_valid == 1 ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Future message with sequence number %u %s buffered.", - hs->in_msg_seq + offset, - hs_buf->is_complete ? "fully" : "partially" ) ); - } - } - } -#endif /* MBEDTLS_DEBUG_C */ - - /* Check if we have buffered and/or fully reassembled the - * next handshake message. */ - hs_buf = &hs->buffering.hs[0]; - if( ( hs_buf->is_valid == 1 ) && ( hs_buf->is_complete == 1 ) ) - { - /* Synthesize a record containing the buffered HS message. */ - size_t msg_len = ( hs_buf->data[1] << 16 ) | - ( hs_buf->data[2] << 8 ) | - hs_buf->data[3]; - - /* Double-check that we haven't accidentally buffered - * a message that doesn't fit into the input buffer. */ - if( msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Next handshake message has been buffered - load" ) ); - MBEDTLS_SSL_DEBUG_BUF( 3, "Buffered handshake message (incl. header)", - hs_buf->data, msg_len + 12 ); - - ssl->in_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->in_hslen = msg_len + 12; - ssl->in_msglen = msg_len + 12; - memcpy( ssl->in_msg, hs_buf->data, ssl->in_hslen ); - - ret = 0; - goto exit; - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Next handshake message %u not or only partially bufffered", - hs->in_msg_seq ) ); - } - - ret = -1; - -exit: - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_load_buffered_message" ) ); - return( ret ); -} - -static int ssl_buffer_make_space( mbedtls_ssl_context *ssl, - size_t desired ) -{ - int offset; - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Attempt to free buffered messages to have %u bytes available", - (unsigned) desired ) ); - - /* Get rid of future records epoch first, if such exist. */ - ssl_free_buffered_record( ssl ); - - /* Check if we have enough space available now. */ - if( desired <= ( MBEDTLS_SSL_DTLS_MAX_BUFFERING - - hs->buffering.total_bytes_buffered ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Enough space available after freeing future epoch record" ) ); - return( 0 ); - } - - /* We don't have enough space to buffer the next expected handshake - * message. Remove buffers used for future messages to gain space, - * starting with the most distant one. */ - for( offset = MBEDTLS_SSL_MAX_BUFFERED_HS - 1; - offset >= 0; offset-- ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Free buffering slot %d to make space for reassembly of next handshake message", - offset ) ); - - ssl_buffering_free_slot( ssl, (uint8_t) offset ); - - /* Check if we have enough space available now. */ - if( desired <= ( MBEDTLS_SSL_DTLS_MAX_BUFFERING - - hs->buffering.total_bytes_buffered ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Enough space available after freeing buffered HS messages" ) ); - return( 0 ); - } - } - - return( -1 ); -} - -static int ssl_buffer_message( mbedtls_ssl_context *ssl ) -{ - int ret = 0; - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - - if( hs == NULL ) - return( 0 ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_buffer_message" ) ); - - switch( ssl->in_msgtype ) - { - case MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC: - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Remember CCS message" ) ); - - hs->buffering.seen_ccs = 1; - break; - - case MBEDTLS_SSL_MSG_HANDSHAKE: - { - unsigned recv_msg_seq_offset; - unsigned recv_msg_seq = ( ssl->in_msg[4] << 8 ) | ssl->in_msg[5]; - mbedtls_ssl_hs_buffer *hs_buf; - size_t msg_len = ssl->in_hslen - 12; - - /* We should never receive an old handshake - * message - double-check nonetheless. */ - if( recv_msg_seq < ssl->handshake->in_msg_seq ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - recv_msg_seq_offset = recv_msg_seq - ssl->handshake->in_msg_seq; - if( recv_msg_seq_offset >= MBEDTLS_SSL_MAX_BUFFERED_HS ) - { - /* Silently ignore -- message too far in the future */ - MBEDTLS_SSL_DEBUG_MSG( 2, - ( "Ignore future HS message with sequence number %u, " - "buffering window %u - %u", - recv_msg_seq, ssl->handshake->in_msg_seq, - ssl->handshake->in_msg_seq + MBEDTLS_SSL_MAX_BUFFERED_HS - 1 ) ); - - goto exit; - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering HS message with sequence number %u, offset %u ", - recv_msg_seq, recv_msg_seq_offset ) ); - - hs_buf = &hs->buffering.hs[ recv_msg_seq_offset ]; - - /* Check if the buffering for this seq nr has already commenced. */ - if( !hs_buf->is_valid ) - { - size_t reassembly_buf_sz; - - hs_buf->is_fragmented = - ( ssl_hs_is_proper_fragment( ssl ) == 1 ); - - /* We copy the message back into the input buffer - * after reassembly, so check that it's not too large. - * This is an implementation-specific limitation - * and not one from the standard, hence it is not - * checked in ssl_check_hs_header(). */ - if( msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN ) - { - /* Ignore message */ - goto exit; - } - - /* Check if we have enough space to buffer the message. */ - if( hs->buffering.total_bytes_buffered > - MBEDTLS_SSL_DTLS_MAX_BUFFERING ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - reassembly_buf_sz = ssl_get_reassembly_buffer_size( msg_len, - hs_buf->is_fragmented ); - - if( reassembly_buf_sz > ( MBEDTLS_SSL_DTLS_MAX_BUFFERING - - hs->buffering.total_bytes_buffered ) ) - { - if( recv_msg_seq_offset > 0 ) - { - /* If we can't buffer a future message because - * of space limitations -- ignore. */ - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future message of size %u would exceed the compile-time limit %u (already %u bytes buffered) -- ignore\n", - (unsigned) msg_len, MBEDTLS_SSL_DTLS_MAX_BUFFERING, - (unsigned) hs->buffering.total_bytes_buffered ) ); - goto exit; - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future message of size %u would exceed the compile-time limit %u (already %u bytes buffered) -- attempt to make space by freeing buffered future messages\n", - (unsigned) msg_len, MBEDTLS_SSL_DTLS_MAX_BUFFERING, - (unsigned) hs->buffering.total_bytes_buffered ) ); - } - - if( ssl_buffer_make_space( ssl, reassembly_buf_sz ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reassembly of next message of size %u (%u with bitmap) would exceed the compile-time limit %u (already %u bytes buffered) -- fail\n", - (unsigned) msg_len, - (unsigned) reassembly_buf_sz, - MBEDTLS_SSL_DTLS_MAX_BUFFERING, - (unsigned) hs->buffering.total_bytes_buffered ) ); - ret = MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; - goto exit; - } - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialize reassembly, total length = %d", - msg_len ) ); - - hs_buf->data = mbedtls_calloc( 1, reassembly_buf_sz ); - if( hs_buf->data == NULL ) - { - ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; - goto exit; - } - hs_buf->data_len = reassembly_buf_sz; - - /* Prepare final header: copy msg_type, length and message_seq, - * then add standardised fragment_offset and fragment_length */ - memcpy( hs_buf->data, ssl->in_msg, 6 ); - memset( hs_buf->data + 6, 0, 3 ); - memcpy( hs_buf->data + 9, hs_buf->data + 1, 3 ); - - hs_buf->is_valid = 1; - - hs->buffering.total_bytes_buffered += reassembly_buf_sz; - } - else - { - /* Make sure msg_type and length are consistent */ - if( memcmp( hs_buf->data, ssl->in_msg, 4 ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "Fragment header mismatch - ignore" ) ); - /* Ignore */ - goto exit; - } - } - - if( !hs_buf->is_complete ) - { - size_t frag_len, frag_off; - unsigned char * const msg = hs_buf->data + 12; - - /* - * Check and copy current fragment - */ - - /* Validation of header fields already done in - * mbedtls_ssl_prepare_handshake_record(). */ - frag_off = ssl_get_hs_frag_off( ssl ); - frag_len = ssl_get_hs_frag_len( ssl ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "adding fragment, offset = %d, length = %d", - frag_off, frag_len ) ); - memcpy( msg + frag_off, ssl->in_msg + 12, frag_len ); - - if( hs_buf->is_fragmented ) - { - unsigned char * const bitmask = msg + msg_len; - ssl_bitmask_set( bitmask, frag_off, frag_len ); - hs_buf->is_complete = ( ssl_bitmask_check( bitmask, - msg_len ) == 0 ); - } - else - { - hs_buf->is_complete = 1; - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "message %scomplete", - hs_buf->is_complete ? "" : "not yet " ) ); - } - - break; - } - - default: - /* We don't buffer other types of messages. */ - break; - } - -exit: - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_buffer_message" ) ); - return( ret ); -} -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -static int ssl_consume_current_message( mbedtls_ssl_context *ssl ) -{ - /* - * Consume last content-layer message and potentially - * update in_msglen which keeps track of the contents' - * consumption state. - * - * (1) Handshake messages: - * Remove last handshake message, move content - * and adapt in_msglen. - * - * (2) Alert messages: - * Consume whole record content, in_msglen = 0. - * - * (3) Change cipher spec: - * Consume whole record content, in_msglen = 0. - * - * (4) Application data: - * Don't do anything - the record layer provides - * the application data as a stream transport - * and consumes through mbedtls_ssl_read only. - * - */ - - /* Case (1): Handshake messages */ - if( ssl->in_hslen != 0 ) - { - /* Hard assertion to be sure that no application data - * is in flight, as corrupting ssl->in_msglen during - * ssl->in_offt != NULL is fatal. */ - if( ssl->in_offt != NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - /* - * Get next Handshake message in the current record - */ - - /* Notes: - * (1) in_hslen is not necessarily the size of the - * current handshake content: If DTLS handshake - * fragmentation is used, that's the fragment - * size instead. Using the total handshake message - * size here is faulty and should be changed at - * some point. - * (2) While it doesn't seem to cause problems, one - * has to be very careful not to assume that in_hslen - * is always <= in_msglen in a sensible communication. - * Again, it's wrong for DTLS handshake fragmentation. - * The following check is therefore mandatory, and - * should not be treated as a silently corrected assertion. - * Additionally, ssl->in_hslen might be arbitrarily out of - * bounds after handling a DTLS message with an unexpected - * sequence number, see mbedtls_ssl_prepare_handshake_record. - */ - if( ssl->in_hslen < ssl->in_msglen ) - { - ssl->in_msglen -= ssl->in_hslen; - memmove( ssl->in_msg, ssl->in_msg + ssl->in_hslen, - ssl->in_msglen ); - - MBEDTLS_SSL_DEBUG_BUF( 4, "remaining content in record", - ssl->in_msg, ssl->in_msglen ); - } - else - { - ssl->in_msglen = 0; - } - - ssl->in_hslen = 0; - } - /* Case (4): Application data */ - else if( ssl->in_offt != NULL ) - { - return( 0 ); - } - /* Everything else (CCS & Alerts) */ - else - { - ssl->in_msglen = 0; - } - - return( 0 ); -} - -static int ssl_record_is_in_progress( mbedtls_ssl_context *ssl ) -{ - if( ssl->in_msglen > 0 ) - return( 1 ); - - return( 0 ); -} - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - -static void ssl_free_buffered_record( mbedtls_ssl_context *ssl ) -{ - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - if( hs == NULL ) - return; - - if( hs->buffering.future_record.data != NULL ) - { - hs->buffering.total_bytes_buffered -= - hs->buffering.future_record.len; - - mbedtls_free( hs->buffering.future_record.data ); - hs->buffering.future_record.data = NULL; - } -} - -static int ssl_load_buffered_record( mbedtls_ssl_context *ssl ) -{ - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - unsigned char * rec; - size_t rec_len; - unsigned rec_epoch; - - if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - return( 0 ); - - if( hs == NULL ) - return( 0 ); - - rec = hs->buffering.future_record.data; - rec_len = hs->buffering.future_record.len; - rec_epoch = hs->buffering.future_record.epoch; - - if( rec == NULL ) - return( 0 ); - - /* Only consider loading future records if the - * input buffer is empty. */ - if( ssl_next_record_is_in_datagram( ssl ) == 1 ) - return( 0 ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_load_buffered_record" ) ); - - if( rec_epoch != ssl->in_epoch ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffered record not from current epoch." ) ); - goto exit; - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Found buffered record from current epoch - load" ) ); - - /* Double-check that the record is not too large */ - if( rec_len > MBEDTLS_SSL_IN_BUFFER_LEN - - (size_t)( ssl->in_hdr - ssl->in_buf ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - memcpy( ssl->in_hdr, rec, rec_len ); - ssl->in_left = rec_len; - ssl->next_record_offset = 0; - - ssl_free_buffered_record( ssl ); - -exit: - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_load_buffered_record" ) ); - return( 0 ); -} - -static int ssl_buffer_future_record( mbedtls_ssl_context *ssl ) -{ - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - size_t const rec_hdr_len = 13; - size_t const total_buf_sz = rec_hdr_len + ssl->in_msglen; - - /* Don't buffer future records outside handshakes. */ - if( hs == NULL ) - return( 0 ); - - /* Only buffer handshake records (we are only interested - * in Finished messages). */ - if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) - return( 0 ); - - /* Don't buffer more than one future epoch record. */ - if( hs->buffering.future_record.data != NULL ) - return( 0 ); - - /* Don't buffer record if there's not enough buffering space remaining. */ - if( total_buf_sz > ( MBEDTLS_SSL_DTLS_MAX_BUFFERING - - hs->buffering.total_bytes_buffered ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future epoch record of size %u would exceed the compile-time limit %u (already %u bytes buffered) -- ignore\n", - (unsigned) total_buf_sz, MBEDTLS_SSL_DTLS_MAX_BUFFERING, - (unsigned) hs->buffering.total_bytes_buffered ) ); - return( 0 ); - } - - /* Buffer record */ - MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffer record from epoch %u", - ssl->in_epoch + 1 ) ); - MBEDTLS_SSL_DEBUG_BUF( 3, "Buffered record", ssl->in_hdr, - rec_hdr_len + ssl->in_msglen ); - - /* ssl_parse_record_header() only considers records - * of the next epoch as candidates for buffering. */ - hs->buffering.future_record.epoch = ssl->in_epoch + 1; - hs->buffering.future_record.len = total_buf_sz; - - hs->buffering.future_record.data = - mbedtls_calloc( 1, hs->buffering.future_record.len ); - if( hs->buffering.future_record.data == NULL ) - { - /* If we run out of RAM trying to buffer a - * record from the next epoch, just ignore. */ - return( 0 ); - } - - memcpy( hs->buffering.future_record.data, ssl->in_hdr, total_buf_sz ); - - hs->buffering.total_bytes_buffered += total_buf_sz; - return( 0 ); -} - -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -static int ssl_get_next_record( mbedtls_ssl_context *ssl ) -{ - int ret; - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - /* We might have buffered a future record; if so, - * and if the epoch matches now, load it. - * On success, this call will set ssl->in_left to - * the length of the buffered record, so that - * the calls to ssl_fetch_input() below will - * essentially be no-ops. */ - ret = ssl_load_buffered_record( ssl ); - if( ret != 0 ) - return( ret ); -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - if( ( ret = mbedtls_ssl_fetch_input( ssl, mbedtls_ssl_hdr_len( ssl ) ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); - return( ret ); - } - - if( ( ret = ssl_parse_record_header( ssl ) ) != 0 ) - { -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ret != MBEDTLS_ERR_SSL_CLIENT_RECONNECT ) - { - if( ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE ) - { - ret = ssl_buffer_future_record( ssl ); - if( ret != 0 ) - return( ret ); - - /* Fall through to handling of unexpected records */ - ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD; - } - - if( ret == MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ) - { - /* Skip unexpected record (but not whole datagram) */ - ssl->next_record_offset = ssl->in_msglen - + mbedtls_ssl_hdr_len( ssl ); - - MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding unexpected record " - "(header)" ) ); - } - else - { - /* Skip invalid record and the rest of the datagram */ - ssl->next_record_offset = 0; - ssl->in_left = 0; - - MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding invalid record " - "(header)" ) ); - } - - /* Get next record */ - return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING ); - } -#endif - return( ret ); - } - - /* - * Read and optionally decrypt the message contents - */ - if( ( ret = mbedtls_ssl_fetch_input( ssl, - mbedtls_ssl_hdr_len( ssl ) + ssl->in_msglen ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); - return( ret ); - } - - /* Done reading this record, get ready for the next one */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - ssl->next_record_offset = ssl->in_msglen + mbedtls_ssl_hdr_len( ssl ); - if( ssl->next_record_offset < ssl->in_left ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "more than one record within datagram" ) ); - } - } - else -#endif - ssl->in_left = 0; - - if( ( ret = ssl_prepare_record_content( ssl ) ) != 0 ) - { -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - /* Silently discard invalid records */ - if( ret == MBEDTLS_ERR_SSL_INVALID_RECORD || - ret == MBEDTLS_ERR_SSL_INVALID_MAC ) - { - /* Except when waiting for Finished as a bad mac here - * probably means something went wrong in the handshake - * (eg wrong psk used, mitm downgrade attempt, etc.) */ - if( ssl->state == MBEDTLS_SSL_CLIENT_FINISHED || - ssl->state == MBEDTLS_SSL_SERVER_FINISHED ) - { -#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES) - if( ret == MBEDTLS_ERR_SSL_INVALID_MAC ) - { - mbedtls_ssl_send_alert_message( ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC ); - } -#endif - return( ret ); - } - -#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) - if( ssl->conf->badmac_limit != 0 && - ++ssl->badmac_seen >= ssl->conf->badmac_limit ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "too many records with bad MAC" ) ); - return( MBEDTLS_ERR_SSL_INVALID_MAC ); - } -#endif - - /* As above, invalid records cause - * dismissal of the whole datagram. */ - - ssl->next_record_offset = 0; - ssl->in_left = 0; - - MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding invalid record (mac)" ) ); - return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING ); - } - - return( ret ); - } - else -#endif - { - /* Error out (and send alert) on invalid records */ -#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES) - if( ret == MBEDTLS_ERR_SSL_INVALID_MAC ) - { - mbedtls_ssl_send_alert_message( ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC ); - } -#endif - return( ret ); - } - } - - return( 0 ); -} - -int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl ) -{ - int ret; - - /* - * Handle particular types of records - */ - if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE ) - { - if( ( ret = mbedtls_ssl_prepare_handshake_record( ssl ) ) != 0 ) - { - return( ret ); - } - } - - if( ssl->in_msgtype == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC ) - { - if( ssl->in_msglen != 1 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid CCS message, len: %d", - ssl->in_msglen ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } - - if( ssl->in_msg[0] != 1 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid CCS message, content: %02x", - ssl->in_msg[0] ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl->state != MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC && - ssl->state != MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC ) - { - if( ssl->handshake == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping ChangeCipherSpec outside handshake" ) ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ); - } - - MBEDTLS_SSL_DEBUG_MSG( 1, ( "received out-of-order ChangeCipherSpec - remember" ) ); - return( MBEDTLS_ERR_SSL_EARLY_MESSAGE ); - } -#endif - } - - if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT ) - { - if( ssl->in_msglen != 2 ) - { - /* Note: Standard allows for more than one 2 byte alert - to be packed in a single message, but Mbed TLS doesn't - currently support this. */ - MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid alert message, len: %d", - ssl->in_msglen ) ); - return( MBEDTLS_ERR_SSL_INVALID_RECORD ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "got an alert message, type: [%d:%d]", - ssl->in_msg[0], ssl->in_msg[1] ) ); - - /* - * Ignore non-fatal alerts, except close_notify and no_renegotiation - */ - if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_FATAL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "is a fatal alert message (msg %d)", - ssl->in_msg[1] ) ); - return( MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE ); - } - - if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING && - ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a close notify message" ) ); - return( MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY ); - } - -#if defined(MBEDTLS_SSL_RENEGOTIATION_ENABLED) - if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING && - ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no renegotiation alert" ) ); - /* Will be handled when trying to parse ServerHello */ - return( 0 ); - } -#endif - -#if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_SRV_C) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 && - ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && - ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING && - ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_CERT ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no_cert" ) ); - /* Will be handled in mbedtls_ssl_parse_certificate() */ - return( 0 ); - } -#endif /* MBEDTLS_SSL_PROTO_SSL3 && MBEDTLS_SSL_SRV_C */ - - /* Silently ignore: fetch new message */ - return MBEDTLS_ERR_SSL_NON_FATAL; - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl->handshake != NULL && - ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) - { - ssl_handshake_wrapup_free_hs_transform( ssl ); - } -#endif - - return( 0 ); -} - -int mbedtls_ssl_send_fatal_handshake_failure( mbedtls_ssl_context *ssl ) -{ - int ret; - - if( ( ret = mbedtls_ssl_send_alert_message( ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ) ) != 0 ) - { - return( ret ); - } - - return( 0 ); -} - -int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl, - unsigned char level, - unsigned char message ) -{ - int ret; - - if( ssl == NULL || ssl->conf == NULL ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> send alert message" ) ); - MBEDTLS_SSL_DEBUG_MSG( 3, ( "send alert level=%u message=%u", level, message )); - - ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT; - ssl->out_msglen = 2; - ssl->out_msg[0] = level; - ssl->out_msg[1] = message; - - if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); - return( ret ); - } - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= send alert message" ) ); - - return( 0 ); -} - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -static void ssl_clear_peer_cert( mbedtls_ssl_session *session ) -{ -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - if( session->peer_cert != NULL ) - { - mbedtls_x509_crt_free( session->peer_cert ); - mbedtls_free( session->peer_cert ); - session->peer_cert = NULL; - } -#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - if( session->peer_cert_digest != NULL ) - { - /* Zeroization is not necessary. */ - mbedtls_free( session->peer_cert_digest ); - session->peer_cert_digest = NULL; - session->peer_cert_digest_type = MBEDTLS_MD_NONE; - session->peer_cert_digest_len = 0; - } -#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ -} -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -/* - * Handshake functions - */ -#if !defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) -/* No certificate support -> dummy functions */ -int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl ) -{ - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate" ) ); - - if( !mbedtls_ssl_ciphersuite_uses_srv_cert( ciphersuite_info ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) ); - ssl->state++; - return( 0 ); - } - - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); -} - -int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) -{ - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) ); - - if( !mbedtls_ssl_ciphersuite_uses_srv_cert( ciphersuite_info ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) ); - ssl->state++; - return( 0 ); - } - - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); -} - -#else /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ -/* Some certificate support -> implement write and parse */ - -int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl ) -{ - int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - size_t i, n; - const mbedtls_x509_crt *crt; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate" ) ); - - if( !mbedtls_ssl_ciphersuite_uses_srv_cert( ciphersuite_info ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) ); - ssl->state++; - return( 0 ); - } - -#if defined(MBEDTLS_SSL_CLI_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) - { - if( ssl->client_auth == 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) ); - ssl->state++; - return( 0 ); - } - -#if defined(MBEDTLS_SSL_PROTO_SSL3) - /* - * If using SSLv3 and got no cert, send an Alert message - * (otherwise an empty Certificate message will be sent). - */ - if( mbedtls_ssl_own_cert( ssl ) == NULL && - ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) - { - ssl->out_msglen = 2; - ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT; - ssl->out_msg[0] = MBEDTLS_SSL_ALERT_LEVEL_WARNING; - ssl->out_msg[1] = MBEDTLS_SSL_ALERT_MSG_NO_CERT; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "got no certificate to send" ) ); - goto write_msg; - } -#endif /* MBEDTLS_SSL_PROTO_SSL3 */ - } -#endif /* MBEDTLS_SSL_CLI_C */ -#if defined(MBEDTLS_SSL_SRV_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) - { - if( mbedtls_ssl_own_cert( ssl ) == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no certificate to send" ) ); - return( MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED ); - } - } -#endif - - MBEDTLS_SSL_DEBUG_CRT( 3, "own certificate", mbedtls_ssl_own_cert( ssl ) ); - - /* - * 0 . 0 handshake type - * 1 . 3 handshake length - * 4 . 6 length of all certs - * 7 . 9 length of cert. 1 - * 10 . n-1 peer certificate - * n . n+2 length of cert. 2 - * n+3 . ... upper level cert, etc. - */ - i = 7; - crt = mbedtls_ssl_own_cert( ssl ); - - while( crt != NULL ) - { - n = crt->raw.len; - if( n > MBEDTLS_SSL_OUT_CONTENT_LEN - 3 - i ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "certificate too large, %d > %d", - i + 3 + n, MBEDTLS_SSL_OUT_CONTENT_LEN ) ); - return( MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE ); - } - - ssl->out_msg[i ] = (unsigned char)( n >> 16 ); - ssl->out_msg[i + 1] = (unsigned char)( n >> 8 ); - ssl->out_msg[i + 2] = (unsigned char)( n ); - - i += 3; memcpy( ssl->out_msg + i, crt->raw.p, n ); - i += n; crt = crt->next; - } - - ssl->out_msg[4] = (unsigned char)( ( i - 7 ) >> 16 ); - ssl->out_msg[5] = (unsigned char)( ( i - 7 ) >> 8 ); - ssl->out_msg[6] = (unsigned char)( ( i - 7 ) ); - - ssl->out_msglen = i; - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE; - -#if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_CLI_C) -write_msg: -#endif - - ssl->state++; - - if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); - return( ret ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write certificate" ) ); - - return( ret ); -} - -#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C) - -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) -static int ssl_check_peer_crt_unchanged( mbedtls_ssl_context *ssl, - unsigned char *crt_buf, - size_t crt_buf_len ) -{ - mbedtls_x509_crt const * const peer_crt = ssl->session->peer_cert; - - if( peer_crt == NULL ) - return( -1 ); - - if( peer_crt->raw.len != crt_buf_len ) - return( -1 ); - - return( memcmp( peer_crt->raw.p, crt_buf, crt_buf_len ) ); -} -#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ -static int ssl_check_peer_crt_unchanged( mbedtls_ssl_context *ssl, - unsigned char *crt_buf, - size_t crt_buf_len ) -{ - int ret; - unsigned char const * const peer_cert_digest = - ssl->session->peer_cert_digest; - mbedtls_md_type_t const peer_cert_digest_type = - ssl->session->peer_cert_digest_type; - mbedtls_md_info_t const * const digest_info = - mbedtls_md_info_from_type( peer_cert_digest_type ); - unsigned char tmp_digest[MBEDTLS_SSL_PEER_CERT_DIGEST_MAX_LEN]; - size_t digest_len; - - if( peer_cert_digest == NULL || digest_info == NULL ) - return( -1 ); - - digest_len = mbedtls_md_get_size( digest_info ); - if( digest_len > MBEDTLS_SSL_PEER_CERT_DIGEST_MAX_LEN ) - return( -1 ); - - ret = mbedtls_md( digest_info, crt_buf, crt_buf_len, tmp_digest ); - if( ret != 0 ) - return( -1 ); - - return( memcmp( tmp_digest, peer_cert_digest, digest_len ) ); -} -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ -#endif /* MBEDTLS_SSL_RENEGOTIATION && MBEDTLS_SSL_CLI_C */ - -/* - * Once the certificate message is read, parse it into a cert chain and - * perform basic checks, but leave actual verification to the caller - */ -static int ssl_parse_certificate_chain( mbedtls_ssl_context *ssl, - mbedtls_x509_crt *chain ) -{ - int ret; -#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C) - int crt_cnt=0; -#endif - size_t i, n; - uint8_t alert; - - if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } - - if( ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE || - ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 3 + 3 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); - } - - i = mbedtls_ssl_hs_hdr_len( ssl ); - - /* - * Same message structure as in mbedtls_ssl_write_certificate() - */ - n = ( ssl->in_msg[i+1] << 8 ) | ssl->in_msg[i+2]; - - if( ssl->in_msg[i] != 0 || - ssl->in_hslen != n + 3 + mbedtls_ssl_hs_hdr_len( ssl ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); - } - - /* Make &ssl->in_msg[i] point to the beginning of the CRT chain. */ - i += 3; - - /* Iterate through and parse the CRTs in the provided chain. */ - while( i < ssl->in_hslen ) - { - /* Check that there's room for the next CRT's length fields. */ - if ( i + 3 > ssl->in_hslen ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); - mbedtls_ssl_send_alert_message( ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); - } - /* In theory, the CRT can be up to 2**24 Bytes, but we don't support - * anything beyond 2**16 ~ 64K. */ - if( ssl->in_msg[i] != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); - mbedtls_ssl_send_alert_message( ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); - } - - /* Read length of the next CRT in the chain. */ - n = ( (unsigned int) ssl->in_msg[i + 1] << 8 ) - | (unsigned int) ssl->in_msg[i + 2]; - i += 3; - - if( n < 128 || i + n > ssl->in_hslen ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); - mbedtls_ssl_send_alert_message( ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); - } - - /* Check if we're handling the first CRT in the chain. */ -#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C) - if( crt_cnt++ == 0 && - ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT && - ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) - { - /* During client-side renegotiation, check that the server's - * end-CRTs hasn't changed compared to the initial handshake, - * mitigating the triple handshake attack. On success, reuse - * the original end-CRT instead of parsing it again. */ - MBEDTLS_SSL_DEBUG_MSG( 3, ( "Check that peer CRT hasn't changed during renegotiation" ) ); - if( ssl_check_peer_crt_unchanged( ssl, - &ssl->in_msg[i], - n ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "new server cert during renegotiation" ) ); - mbedtls_ssl_send_alert_message( ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); - } - - /* Now we can safely free the original chain. */ - ssl_clear_peer_cert( ssl->session ); - } -#endif /* MBEDTLS_SSL_RENEGOTIATION && MBEDTLS_SSL_CLI_C */ - - /* Parse the next certificate in the chain. */ -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - ret = mbedtls_x509_crt_parse_der( chain, ssl->in_msg + i, n ); -#else - /* If we don't need to store the CRT chain permanently, parse - * it in-place from the input buffer instead of making a copy. */ - ret = mbedtls_x509_crt_parse_der_nocopy( chain, ssl->in_msg + i, n ); -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - switch( ret ) - { - case 0: /*ok*/ - case MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + MBEDTLS_ERR_OID_NOT_FOUND: - /* Ignore certificate with an unknown algorithm: maybe a - prior certificate was already trusted. */ - break; - - case MBEDTLS_ERR_X509_ALLOC_FAILED: - alert = MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR; - goto crt_parse_der_failed; - - case MBEDTLS_ERR_X509_UNKNOWN_VERSION: - alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; - goto crt_parse_der_failed; - - default: - alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT; - crt_parse_der_failed: - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, alert ); - MBEDTLS_SSL_DEBUG_RET( 1, " mbedtls_x509_crt_parse_der", ret ); - return( ret ); - } - - i += n; - } - - MBEDTLS_SSL_DEBUG_CRT( 3, "peer certificate", chain ); - return( 0 ); -} - -#if defined(MBEDTLS_SSL_SRV_C) -static int ssl_srv_check_client_no_crt_notification( mbedtls_ssl_context *ssl ) -{ - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) - return( -1 ); - -#if defined(MBEDTLS_SSL_PROTO_SSL3) - /* - * Check if the client sent an empty certificate - */ - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) - { - if( ssl->in_msglen == 2 && - ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT && - ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING && - ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_CERT ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "SSLv3 client has no certificate" ) ); - return( 0 ); - } - - return( -1 ); - } -#endif /* MBEDTLS_SSL_PROTO_SSL3 */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->in_hslen == 3 + mbedtls_ssl_hs_hdr_len( ssl ) && - ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && - ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE && - memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ), "\0\0\0", 3 ) == 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLSv1 client has no certificate" ) ); - return( 0 ); - } - - return( -1 ); -#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ - MBEDTLS_SSL_PROTO_TLS1_2 */ -} -#endif /* MBEDTLS_SSL_SRV_C */ - -/* Check if a certificate message is expected. - * Return either - * - SSL_CERTIFICATE_EXPECTED, or - * - SSL_CERTIFICATE_SKIP - * indicating whether a Certificate message is expected or not. - */ -#define SSL_CERTIFICATE_EXPECTED 0 -#define SSL_CERTIFICATE_SKIP 1 -static int ssl_parse_certificate_coordinate( mbedtls_ssl_context *ssl, - int authmode ) -{ - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->transform_negotiate->ciphersuite_info; - - if( !mbedtls_ssl_ciphersuite_uses_srv_cert( ciphersuite_info ) ) - return( SSL_CERTIFICATE_SKIP ); - -#if defined(MBEDTLS_SSL_SRV_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) - { - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) - return( SSL_CERTIFICATE_SKIP ); - - if( authmode == MBEDTLS_SSL_VERIFY_NONE ) - { - ssl->session_negotiate->verify_result = - MBEDTLS_X509_BADCERT_SKIP_VERIFY; - return( SSL_CERTIFICATE_SKIP ); - } - } -#else - ((void) authmode); -#endif /* MBEDTLS_SSL_SRV_C */ - - return( SSL_CERTIFICATE_EXPECTED ); -} - -static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl, - int authmode, - mbedtls_x509_crt *chain, - void *rs_ctx ) -{ - int ret = 0; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->transform_negotiate->ciphersuite_info; - int have_ca_chain = 0; - - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *); - void *p_vrfy; - - if( authmode == MBEDTLS_SSL_VERIFY_NONE ) - return( 0 ); - - if( ssl->f_vrfy != NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "Use context-specific verification callback" ) ); - f_vrfy = ssl->f_vrfy; - p_vrfy = ssl->p_vrfy; - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "Use configuration-specific verification callback" ) ); - f_vrfy = ssl->conf->f_vrfy; - p_vrfy = ssl->conf->p_vrfy; - } - - /* - * Main check: verify certificate - */ -#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) - if( ssl->conf->f_ca_cb != NULL ) - { - ((void) rs_ctx); - have_ca_chain = 1; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "use CA callback for X.509 CRT verification" ) ); - ret = mbedtls_x509_crt_verify_with_ca_cb( - chain, - ssl->conf->f_ca_cb, - ssl->conf->p_ca_cb, - ssl->conf->cert_profile, - ssl->hostname, - &ssl->session_negotiate->verify_result, - f_vrfy, p_vrfy ); - } - else -#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */ - { - mbedtls_x509_crt *ca_chain; - mbedtls_x509_crl *ca_crl; - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - if( ssl->handshake->sni_ca_chain != NULL ) - { - ca_chain = ssl->handshake->sni_ca_chain; - ca_crl = ssl->handshake->sni_ca_crl; - } - else -#endif - { - ca_chain = ssl->conf->ca_chain; - ca_crl = ssl->conf->ca_crl; - } - - if( ca_chain != NULL ) - have_ca_chain = 1; - - ret = mbedtls_x509_crt_verify_restartable( - chain, - ca_chain, ca_crl, - ssl->conf->cert_profile, - ssl->hostname, - &ssl->session_negotiate->verify_result, - f_vrfy, p_vrfy, rs_ctx ); - } - - if( ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "x509_verify_cert", ret ); - } - -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) - return( MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS ); -#endif - - /* - * Secondary checks: always done, but change 'ret' only if it was 0 - */ - -#if defined(MBEDTLS_ECP_C) - { - const mbedtls_pk_context *pk = &chain->pk; - - /* If certificate uses an EC key, make sure the curve is OK */ - if( mbedtls_pk_can_do( pk, MBEDTLS_PK_ECKEY ) && - mbedtls_ssl_check_curve( ssl, mbedtls_pk_ec( *pk )->grp.id ) != 0 ) - { - ssl->session_negotiate->verify_result |= MBEDTLS_X509_BADCERT_BAD_KEY; - - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (EC key curve)" ) ); - if( ret == 0 ) - ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE; - } - } -#endif /* MBEDTLS_ECP_C */ - - if( mbedtls_ssl_check_cert_usage( chain, - ciphersuite_info, - ! ssl->conf->endpoint, - &ssl->session_negotiate->verify_result ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (usage extensions)" ) ); - if( ret == 0 ) - ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE; - } - - /* mbedtls_x509_crt_verify_with_profile is supposed to report a - * verification failure through MBEDTLS_ERR_X509_CERT_VERIFY_FAILED, - * with details encoded in the verification flags. All other kinds - * of error codes, including those from the user provided f_vrfy - * functions, are treated as fatal and lead to a failure of - * ssl_parse_certificate even if verification was optional. */ - if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL && - ( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED || - ret == MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ) ) - { - ret = 0; - } - - if( have_ca_chain == 0 && authmode == MBEDTLS_SSL_VERIFY_REQUIRED ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no CA chain" ) ); - ret = MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED; - } - - if( ret != 0 ) - { - uint8_t alert; - - /* The certificate may have been rejected for several reasons. - Pick one and send the corresponding alert. Which alert to send - may be a subject of debate in some cases. */ - if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_OTHER ) - alert = MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED; - else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_CN_MISMATCH ) - alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT; - else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_KEY_USAGE ) - alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; - else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXT_KEY_USAGE ) - alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; - else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NS_CERT_TYPE ) - alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; - else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_PK ) - alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; - else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_KEY ) - alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; - else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXPIRED ) - alert = MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED; - else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_REVOKED ) - alert = MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED; - else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NOT_TRUSTED ) - alert = MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA; - else - alert = MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN; - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - alert ); - } - -#if defined(MBEDTLS_DEBUG_C) - if( ssl->session_negotiate->verify_result != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "! Certificate verification flags %x", - ssl->session_negotiate->verify_result ) ); - } - else - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "Certificate verification flags clear" ) ); - } -#endif /* MBEDTLS_DEBUG_C */ - - return( ret ); -} - -#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) -static int ssl_remember_peer_crt_digest( mbedtls_ssl_context *ssl, - unsigned char *start, size_t len ) -{ - int ret; - /* Remember digest of the peer's end-CRT. */ - ssl->session_negotiate->peer_cert_digest = - mbedtls_calloc( 1, MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN ); - if( ssl->session_negotiate->peer_cert_digest == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", - sizeof( MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN ) ) ); - mbedtls_ssl_send_alert_message( ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); - - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - } - - ret = mbedtls_md( mbedtls_md_info_from_type( - MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE ), - start, len, - ssl->session_negotiate->peer_cert_digest ); - - ssl->session_negotiate->peer_cert_digest_type = - MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE; - ssl->session_negotiate->peer_cert_digest_len = - MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN; - - return( ret ); -} - -static int ssl_remember_peer_pubkey( mbedtls_ssl_context *ssl, - unsigned char *start, size_t len ) -{ - unsigned char *end = start + len; - int ret; - - /* Make a copy of the peer's raw public key. */ - mbedtls_pk_init( &ssl->handshake->peer_pubkey ); - ret = mbedtls_pk_parse_subpubkey( &start, end, - &ssl->handshake->peer_pubkey ); - if( ret != 0 ) - { - /* We should have parsed the public key before. */ - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - return( 0 ); -} -#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - -int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) -{ - int ret = 0; - int crt_expected; -#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - const int authmode = ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET - ? ssl->handshake->sni_authmode - : ssl->conf->authmode; -#else - const int authmode = ssl->conf->authmode; -#endif - void *rs_ctx = NULL; - mbedtls_x509_crt *chain = NULL; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) ); - - crt_expected = ssl_parse_certificate_coordinate( ssl, authmode ); - if( crt_expected == SSL_CERTIFICATE_SKIP ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) ); - goto exit; - } - -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ssl->handshake->ecrs_enabled && - ssl->handshake->ecrs_state == ssl_ecrs_crt_verify ) - { - chain = ssl->handshake->ecrs_peer_cert; - ssl->handshake->ecrs_peer_cert = NULL; - goto crt_verify; - } -#endif - - if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) - { - /* mbedtls_ssl_read_record may have sent an alert already. We - let it decide whether to alert. */ - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); - goto exit; - } - -#if defined(MBEDTLS_SSL_SRV_C) - if( ssl_srv_check_client_no_crt_notification( ssl ) == 0 ) - { - ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING; - - if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL ) - ret = 0; - else - ret = MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE; - - goto exit; - } -#endif /* MBEDTLS_SSL_SRV_C */ - - /* Clear existing peer CRT structure in case we tried to - * reuse a session but it failed, and allocate a new one. */ - ssl_clear_peer_cert( ssl->session_negotiate ); - - chain = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) ); - if( chain == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", - sizeof( mbedtls_x509_crt ) ) ); - mbedtls_ssl_send_alert_message( ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); - - ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; - goto exit; - } - mbedtls_x509_crt_init( chain ); - - ret = ssl_parse_certificate_chain( ssl, chain ); - if( ret != 0 ) - goto exit; - -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ssl->handshake->ecrs_enabled) - ssl->handshake->ecrs_state = ssl_ecrs_crt_verify; - -crt_verify: - if( ssl->handshake->ecrs_enabled) - rs_ctx = &ssl->handshake->ecrs_ctx; -#endif - - ret = ssl_parse_certificate_verify( ssl, authmode, - chain, rs_ctx ); - if( ret != 0 ) - goto exit; - -#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - { - unsigned char *crt_start, *pk_start; - size_t crt_len, pk_len; - - /* We parse the CRT chain without copying, so - * these pointers point into the input buffer, - * and are hence still valid after freeing the - * CRT chain. */ - - crt_start = chain->raw.p; - crt_len = chain->raw.len; - - pk_start = chain->pk_raw.p; - pk_len = chain->pk_raw.len; - - /* Free the CRT structures before computing - * digest and copying the peer's public key. */ - mbedtls_x509_crt_free( chain ); - mbedtls_free( chain ); - chain = NULL; - - ret = ssl_remember_peer_crt_digest( ssl, crt_start, crt_len ); - if( ret != 0 ) - goto exit; - - ret = ssl_remember_peer_pubkey( ssl, pk_start, pk_len ); - if( ret != 0 ) - goto exit; - } -#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - /* Pass ownership to session structure. */ - ssl->session_negotiate->peer_cert = chain; - chain = NULL; -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate" ) ); - -exit: - - if( ret == 0 ) - ssl->state++; - -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ret == MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS ) - { - ssl->handshake->ecrs_peer_cert = chain; - chain = NULL; - } -#endif - - if( chain != NULL ) - { - mbedtls_x509_crt_free( chain ); - mbedtls_free( chain ); - } - - return( ret ); -} -#endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ - -int mbedtls_ssl_write_change_cipher_spec( mbedtls_ssl_context *ssl ) -{ - int ret; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write change cipher spec" ) ); - - ssl->out_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC; - ssl->out_msglen = 1; - ssl->out_msg[0] = 1; - - ssl->state++; - - if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); - return( ret ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write change cipher spec" ) ); - - return( 0 ); -} - -int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl ) -{ - int ret; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse change cipher spec" ) ); - - if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); - return( ret ); - } - - if( ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad change cipher spec message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } - - /* CCS records are only accepted if they have length 1 and content '1', - * so we don't need to check this here. */ - - /* - * Switch to our negotiated transform and session parameters for inbound - * data. - */ - MBEDTLS_SSL_DEBUG_MSG( 3, ( "switching to new transform spec for inbound data" ) ); - ssl->transform_in = ssl->transform_negotiate; - ssl->session_in = ssl->session_negotiate; - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) - ssl_dtls_replay_reset( ssl ); -#endif - - /* Increment epoch */ - if( ++ssl->in_epoch == 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS epoch would wrap" ) ); - /* This is highly unlikely to happen for legitimate reasons, so - treat it as an attack and don't send an alert. */ - return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING ); - } - } - else -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - memset( ssl->in_ctr, 0, 8 ); - - ssl_update_in_pointers( ssl, ssl->transform_negotiate ); - -#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) - if( mbedtls_ssl_hw_record_activate != NULL ) - { - if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_INBOUND ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - } - } -#endif - - ssl->state++; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse change cipher spec" ) ); - - return( 0 ); -} - -void mbedtls_ssl_optimize_checksum( mbedtls_ssl_context *ssl, - const mbedtls_ssl_ciphersuite_t *ciphersuite_info ) -{ - ((void) ciphersuite_info); - -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) - if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 ) - ssl->handshake->update_checksum = ssl_update_checksum_md5sha1; - else -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_SHA512_C) - if( ciphersuite_info->mac == MBEDTLS_MD_SHA384 ) - ssl->handshake->update_checksum = ssl_update_checksum_sha384; - else -#endif -#if defined(MBEDTLS_SHA256_C) - if( ciphersuite_info->mac != MBEDTLS_MD_SHA384 ) - ssl->handshake->update_checksum = ssl_update_checksum_sha256; - else -#endif -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return; - } -} - -void mbedtls_ssl_reset_checksum( mbedtls_ssl_context *ssl ) -{ -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) - mbedtls_md5_starts_ret( &ssl->handshake->fin_md5 ); - mbedtls_sha1_starts_ret( &ssl->handshake->fin_sha1 ); -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_SHA256_C) -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_hash_abort( &ssl->handshake->fin_sha256_psa ); - psa_hash_setup( &ssl->handshake->fin_sha256_psa, PSA_ALG_SHA_256 ); -#else - mbedtls_sha256_starts_ret( &ssl->handshake->fin_sha256, 0 ); -#endif -#endif -#if defined(MBEDTLS_SHA512_C) -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_hash_abort( &ssl->handshake->fin_sha384_psa ); - psa_hash_setup( &ssl->handshake->fin_sha384_psa, PSA_ALG_SHA_384 ); -#else - mbedtls_sha512_starts_ret( &ssl->handshake->fin_sha512, 1 ); -#endif -#endif -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ -} - -static void ssl_update_checksum_start( mbedtls_ssl_context *ssl, - const unsigned char *buf, size_t len ) -{ -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) - mbedtls_md5_update_ret( &ssl->handshake->fin_md5 , buf, len ); - mbedtls_sha1_update_ret( &ssl->handshake->fin_sha1, buf, len ); -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_SHA256_C) -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_hash_update( &ssl->handshake->fin_sha256_psa, buf, len ); -#else - mbedtls_sha256_update_ret( &ssl->handshake->fin_sha256, buf, len ); -#endif -#endif -#if defined(MBEDTLS_SHA512_C) -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_hash_update( &ssl->handshake->fin_sha384_psa, buf, len ); -#else - mbedtls_sha512_update_ret( &ssl->handshake->fin_sha512, buf, len ); -#endif -#endif -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ -} - -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) -static void ssl_update_checksum_md5sha1( mbedtls_ssl_context *ssl, - const unsigned char *buf, size_t len ) -{ - mbedtls_md5_update_ret( &ssl->handshake->fin_md5 , buf, len ); - mbedtls_sha1_update_ret( &ssl->handshake->fin_sha1, buf, len ); -} -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_SHA256_C) -static void ssl_update_checksum_sha256( mbedtls_ssl_context *ssl, - const unsigned char *buf, size_t len ) -{ -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_hash_update( &ssl->handshake->fin_sha256_psa, buf, len ); -#else - mbedtls_sha256_update_ret( &ssl->handshake->fin_sha256, buf, len ); -#endif -} -#endif - -#if defined(MBEDTLS_SHA512_C) -static void ssl_update_checksum_sha384( mbedtls_ssl_context *ssl, - const unsigned char *buf, size_t len ) -{ -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_hash_update( &ssl->handshake->fin_sha384_psa, buf, len ); -#else - mbedtls_sha512_update_ret( &ssl->handshake->fin_sha512, buf, len ); -#endif -} -#endif -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -#if defined(MBEDTLS_SSL_PROTO_SSL3) -static void ssl_calc_finished_ssl( - mbedtls_ssl_context *ssl, unsigned char *buf, int from ) -{ - const char *sender; - mbedtls_md5_context md5; - mbedtls_sha1_context sha1; - - unsigned char padbuf[48]; - unsigned char md5sum[16]; - unsigned char sha1sum[20]; - - mbedtls_ssl_session *session = ssl->session_negotiate; - if( !session ) - session = ssl->session; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished ssl" ) ); - - mbedtls_md5_init( &md5 ); - mbedtls_sha1_init( &sha1 ); - - mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 ); - mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 ); - - /* - * SSLv3: - * hash = - * MD5( master + pad2 + - * MD5( handshake + sender + master + pad1 ) ) - * + SHA1( master + pad2 + - * SHA1( handshake + sender + master + pad1 ) ) - */ - -#if !defined(MBEDTLS_MD5_ALT) - MBEDTLS_SSL_DEBUG_BUF( 4, "finished md5 state", (unsigned char *) - md5.state, sizeof( md5.state ) ); -#endif - -#if !defined(MBEDTLS_SHA1_ALT) - MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *) - sha1.state, sizeof( sha1.state ) ); -#endif - - sender = ( from == MBEDTLS_SSL_IS_CLIENT ) ? "CLNT" - : "SRVR"; - - memset( padbuf, 0x36, 48 ); - - mbedtls_md5_update_ret( &md5, (const unsigned char *) sender, 4 ); - mbedtls_md5_update_ret( &md5, session->master, 48 ); - mbedtls_md5_update_ret( &md5, padbuf, 48 ); - mbedtls_md5_finish_ret( &md5, md5sum ); - - mbedtls_sha1_update_ret( &sha1, (const unsigned char *) sender, 4 ); - mbedtls_sha1_update_ret( &sha1, session->master, 48 ); - mbedtls_sha1_update_ret( &sha1, padbuf, 40 ); - mbedtls_sha1_finish_ret( &sha1, sha1sum ); - - memset( padbuf, 0x5C, 48 ); - - mbedtls_md5_starts_ret( &md5 ); - mbedtls_md5_update_ret( &md5, session->master, 48 ); - mbedtls_md5_update_ret( &md5, padbuf, 48 ); - mbedtls_md5_update_ret( &md5, md5sum, 16 ); - mbedtls_md5_finish_ret( &md5, buf ); - - mbedtls_sha1_starts_ret( &sha1 ); - mbedtls_sha1_update_ret( &sha1, session->master, 48 ); - mbedtls_sha1_update_ret( &sha1, padbuf , 40 ); - mbedtls_sha1_update_ret( &sha1, sha1sum, 20 ); - mbedtls_sha1_finish_ret( &sha1, buf + 16 ); - - MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, 36 ); - - mbedtls_md5_free( &md5 ); - mbedtls_sha1_free( &sha1 ); - - mbedtls_platform_zeroize( padbuf, sizeof( padbuf ) ); - mbedtls_platform_zeroize( md5sum, sizeof( md5sum ) ); - mbedtls_platform_zeroize( sha1sum, sizeof( sha1sum ) ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); -} -#endif /* MBEDTLS_SSL_PROTO_SSL3 */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) -static void ssl_calc_finished_tls( - mbedtls_ssl_context *ssl, unsigned char *buf, int from ) -{ - int len = 12; - const char *sender; - mbedtls_md5_context md5; - mbedtls_sha1_context sha1; - unsigned char padbuf[36]; - - mbedtls_ssl_session *session = ssl->session_negotiate; - if( !session ) - session = ssl->session; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls" ) ); - - mbedtls_md5_init( &md5 ); - mbedtls_sha1_init( &sha1 ); - - mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 ); - mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 ); - - /* - * TLSv1: - * hash = PRF( master, finished_label, - * MD5( handshake ) + SHA1( handshake ) )[0..11] - */ - -#if !defined(MBEDTLS_MD5_ALT) - MBEDTLS_SSL_DEBUG_BUF( 4, "finished md5 state", (unsigned char *) - md5.state, sizeof( md5.state ) ); -#endif - -#if !defined(MBEDTLS_SHA1_ALT) - MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *) - sha1.state, sizeof( sha1.state ) ); -#endif - - sender = ( from == MBEDTLS_SSL_IS_CLIENT ) - ? "client finished" - : "server finished"; - - mbedtls_md5_finish_ret( &md5, padbuf ); - mbedtls_sha1_finish_ret( &sha1, padbuf + 16 ); - - ssl->handshake->tls_prf( session->master, 48, sender, - padbuf, 36, buf, len ); - - MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len ); - - mbedtls_md5_free( &md5 ); - mbedtls_sha1_free( &sha1 ); - - mbedtls_platform_zeroize( padbuf, sizeof( padbuf ) ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); -} -#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_SHA256_C) -static void ssl_calc_finished_tls_sha256( - mbedtls_ssl_context *ssl, unsigned char *buf, int from ) -{ - int len = 12; - const char *sender; - unsigned char padbuf[32]; -#if defined(MBEDTLS_USE_PSA_CRYPTO) - size_t hash_size; - psa_hash_operation_t sha256_psa = PSA_HASH_OPERATION_INIT; - psa_status_t status; -#else - mbedtls_sha256_context sha256; -#endif - - mbedtls_ssl_session *session = ssl->session_negotiate; - if( !session ) - session = ssl->session; - - sender = ( from == MBEDTLS_SSL_IS_CLIENT ) - ? "client finished" - : "server finished"; - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - sha256_psa = psa_hash_operation_init(); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc PSA finished tls sha256" ) ); - - status = psa_hash_clone( &ssl->handshake->fin_sha256_psa, &sha256_psa ); - if( status != PSA_SUCCESS ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash clone failed" ) ); - return; - } - - status = psa_hash_finish( &sha256_psa, padbuf, sizeof( padbuf ), &hash_size ); - if( status != PSA_SUCCESS ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash finish failed" ) ); - return; - } - MBEDTLS_SSL_DEBUG_BUF( 3, "PSA calculated padbuf", padbuf, 32 ); -#else - - mbedtls_sha256_init( &sha256 ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls sha256" ) ); - - mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 ); - - /* - * TLSv1.2: - * hash = PRF( master, finished_label, - * Hash( handshake ) )[0.11] - */ - -#if !defined(MBEDTLS_SHA256_ALT) - MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha2 state", (unsigned char *) - sha256.state, sizeof( sha256.state ) ); -#endif - - mbedtls_sha256_finish_ret( &sha256, padbuf ); - mbedtls_sha256_free( &sha256 ); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - - ssl->handshake->tls_prf( session->master, 48, sender, - padbuf, 32, buf, len ); - - MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len ); - - mbedtls_platform_zeroize( padbuf, sizeof( padbuf ) ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); -} -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) -static void ssl_calc_finished_tls_sha384( - mbedtls_ssl_context *ssl, unsigned char *buf, int from ) -{ - int len = 12; - const char *sender; - unsigned char padbuf[48]; -#if defined(MBEDTLS_USE_PSA_CRYPTO) - size_t hash_size; - psa_hash_operation_t sha384_psa = PSA_HASH_OPERATION_INIT; - psa_status_t status; -#else - mbedtls_sha512_context sha512; -#endif - - mbedtls_ssl_session *session = ssl->session_negotiate; - if( !session ) - session = ssl->session; - - sender = ( from == MBEDTLS_SSL_IS_CLIENT ) - ? "client finished" - : "server finished"; - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - sha384_psa = psa_hash_operation_init(); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc PSA finished tls sha384" ) ); - - status = psa_hash_clone( &ssl->handshake->fin_sha384_psa, &sha384_psa ); - if( status != PSA_SUCCESS ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash clone failed" ) ); - return; - } - - status = psa_hash_finish( &sha384_psa, padbuf, sizeof( padbuf ), &hash_size ); - if( status != PSA_SUCCESS ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash finish failed" ) ); - return; - } - MBEDTLS_SSL_DEBUG_BUF( 3, "PSA calculated padbuf", padbuf, 48 ); -#else - mbedtls_sha512_init( &sha512 ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls sha384" ) ); - - mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 ); - - /* - * TLSv1.2: - * hash = PRF( master, finished_label, - * Hash( handshake ) )[0.11] - */ - -#if !defined(MBEDTLS_SHA512_ALT) - MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha512 state", (unsigned char *) - sha512.state, sizeof( sha512.state ) ); -#endif - - mbedtls_sha512_finish_ret( &sha512, padbuf ); - mbedtls_sha512_free( &sha512 ); -#endif - - ssl->handshake->tls_prf( session->master, 48, sender, - padbuf, 48, buf, len ); - - MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len ); - - mbedtls_platform_zeroize( padbuf, sizeof( padbuf ) ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); -} -#endif /* MBEDTLS_SHA512_C */ -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -static void ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl ) -{ - MBEDTLS_SSL_DEBUG_MSG( 3, ( "=> handshake wrapup: final free" ) ); - - /* - * Free our handshake params - */ - mbedtls_ssl_handshake_free( ssl ); - mbedtls_free( ssl->handshake ); - ssl->handshake = NULL; - - /* - * Free the previous transform and swith in the current one - */ - if( ssl->transform ) - { - mbedtls_ssl_transform_free( ssl->transform ); - mbedtls_free( ssl->transform ); - } - ssl->transform = ssl->transform_negotiate; - ssl->transform_negotiate = NULL; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "<= handshake wrapup: final free" ) ); -} - -void mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl ) -{ - int resume = ssl->handshake->resume; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "=> handshake wrapup" ) ); - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) - { - ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_DONE; - ssl->renego_records_seen = 0; - } -#endif - - /* - * Free the previous session and switch in the current one - */ - if( ssl->session ) - { -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - /* RFC 7366 3.1: keep the EtM state */ - ssl->session_negotiate->encrypt_then_mac = - ssl->session->encrypt_then_mac; -#endif - - mbedtls_ssl_session_free( ssl->session ); - mbedtls_free( ssl->session ); - } - ssl->session = ssl->session_negotiate; - ssl->session_negotiate = NULL; - - /* - * Add cache entry - */ - if( ssl->conf->f_set_cache != NULL && - ssl->session->id_len != 0 && - resume == 0 ) - { - if( ssl->conf->f_set_cache( ssl->conf->p_cache, ssl->session ) != 0 ) - MBEDTLS_SSL_DEBUG_MSG( 1, ( "cache did not store session" ) ); - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl->handshake->flight != NULL ) - { - /* Cancel handshake timer */ - ssl_set_timer( ssl, 0 ); - - /* Keep last flight around in case we need to resend it: - * we need the handshake and transform structures for that */ - MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip freeing handshake and transform" ) ); - } - else -#endif - ssl_handshake_wrapup_free_hs_transform( ssl ); - - ssl->state++; - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "<= handshake wrapup" ) ); -} - -int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl ) -{ - int ret, hash_len; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write finished" ) ); - - ssl_update_out_pointers( ssl, ssl->transform_negotiate ); - - ssl->handshake->calc_finished( ssl, ssl->out_msg + 4, ssl->conf->endpoint ); - - /* - * RFC 5246 7.4.9 (Page 63) says 12 is the default length and ciphersuites - * may define some other value. Currently (early 2016), no defined - * ciphersuite does this (and this is unlikely to change as activity has - * moved to TLS 1.3 now) so we can keep the hardcoded 12 here. - */ - hash_len = ( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) ? 36 : 12; - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - ssl->verify_data_len = hash_len; - memcpy( ssl->own_verify_data, ssl->out_msg + 4, hash_len ); -#endif - - ssl->out_msglen = 4 + hash_len; - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = MBEDTLS_SSL_HS_FINISHED; - - /* - * In case of session resuming, invert the client and server - * ChangeCipherSpec messages order. - */ - if( ssl->handshake->resume != 0 ) - { -#if defined(MBEDTLS_SSL_CLI_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) - ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP; -#endif -#if defined(MBEDTLS_SSL_SRV_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) - ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC; -#endif - } - else - ssl->state++; - - /* - * Switch to our negotiated transform and session parameters for outbound - * data. - */ - MBEDTLS_SSL_DEBUG_MSG( 3, ( "switching to new transform spec for outbound data" ) ); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - unsigned char i; - - /* Remember current epoch settings for resending */ - ssl->handshake->alt_transform_out = ssl->transform_out; - memcpy( ssl->handshake->alt_out_ctr, ssl->cur_out_ctr, 8 ); - - /* Set sequence_number to zero */ - memset( ssl->cur_out_ctr + 2, 0, 6 ); - - /* Increment epoch */ - for( i = 2; i > 0; i-- ) - if( ++ssl->cur_out_ctr[i - 1] != 0 ) - break; - - /* The loop goes to its end iff the counter is wrapping */ - if( i == 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS epoch would wrap" ) ); - return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING ); - } - } - else -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - memset( ssl->cur_out_ctr, 0, 8 ); - - ssl->transform_out = ssl->transform_negotiate; - ssl->session_out = ssl->session_negotiate; - -#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) - if( mbedtls_ssl_hw_record_activate != NULL ) - { - if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_OUTBOUND ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret ); - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - } - } -#endif - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - mbedtls_ssl_send_flight_completed( ssl ); -#endif - - if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); - return( ret ); - } - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret ); - return( ret ); - } -#endif - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write finished" ) ); - - return( 0 ); -} - -#if defined(MBEDTLS_SSL_PROTO_SSL3) -#define SSL_MAX_HASH_LEN 36 -#else -#define SSL_MAX_HASH_LEN 12 -#endif - -int mbedtls_ssl_parse_finished( mbedtls_ssl_context *ssl ) -{ - int ret; - unsigned int hash_len; - unsigned char buf[SSL_MAX_HASH_LEN]; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse finished" ) ); - - ssl->handshake->calc_finished( ssl, buf, ssl->conf->endpoint ^ 1 ); - - if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); - return( ret ); - } - - if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } - - /* There is currently no ciphersuite using another length with TLS 1.2 */ -#if defined(MBEDTLS_SSL_PROTO_SSL3) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) - hash_len = 36; - else -#endif - hash_len = 12; - - if( ssl->in_msg[0] != MBEDTLS_SSL_HS_FINISHED || - ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + hash_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_FINISHED ); - } - - if( mbedtls_ssl_safer_memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ), - buf, hash_len ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_FINISHED ); - } - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - ssl->verify_data_len = hash_len; - memcpy( ssl->peer_verify_data, buf, hash_len ); -#endif - - if( ssl->handshake->resume != 0 ) - { -#if defined(MBEDTLS_SSL_CLI_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) - ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC; -#endif -#if defined(MBEDTLS_SSL_SRV_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) - ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP; -#endif - } - else - ssl->state++; - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - mbedtls_ssl_recv_flight_completed( ssl ); -#endif - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse finished" ) ); - - return( 0 ); -} - -static void ssl_handshake_params_init( mbedtls_ssl_handshake_params *handshake ) -{ - memset( handshake, 0, sizeof( mbedtls_ssl_handshake_params ) ); - -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) - mbedtls_md5_init( &handshake->fin_md5 ); - mbedtls_sha1_init( &handshake->fin_sha1 ); - mbedtls_md5_starts_ret( &handshake->fin_md5 ); - mbedtls_sha1_starts_ret( &handshake->fin_sha1 ); -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_SHA256_C) -#if defined(MBEDTLS_USE_PSA_CRYPTO) - handshake->fin_sha256_psa = psa_hash_operation_init(); - psa_hash_setup( &handshake->fin_sha256_psa, PSA_ALG_SHA_256 ); -#else - mbedtls_sha256_init( &handshake->fin_sha256 ); - mbedtls_sha256_starts_ret( &handshake->fin_sha256, 0 ); -#endif -#endif -#if defined(MBEDTLS_SHA512_C) -#if defined(MBEDTLS_USE_PSA_CRYPTO) - handshake->fin_sha384_psa = psa_hash_operation_init(); - psa_hash_setup( &handshake->fin_sha384_psa, PSA_ALG_SHA_384 ); -#else - mbedtls_sha512_init( &handshake->fin_sha512 ); - mbedtls_sha512_starts_ret( &handshake->fin_sha512, 1 ); -#endif -#endif -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - - handshake->update_checksum = ssl_update_checksum_start; - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) - mbedtls_ssl_sig_hash_set_init( &handshake->hash_algs ); -#endif - -#if defined(MBEDTLS_DHM_C) - mbedtls_dhm_init( &handshake->dhm_ctx ); -#endif -#if defined(MBEDTLS_ECDH_C) - mbedtls_ecdh_init( &handshake->ecdh_ctx ); -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - mbedtls_ecjpake_init( &handshake->ecjpake_ctx ); -#if defined(MBEDTLS_SSL_CLI_C) - handshake->ecjpake_cache = NULL; - handshake->ecjpake_cache_len = 0; -#endif -#endif - -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - mbedtls_x509_crt_restart_init( &handshake->ecrs_ctx ); -#endif - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - handshake->sni_authmode = MBEDTLS_SSL_VERIFY_UNSET; -#endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) && \ - !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - mbedtls_pk_init( &handshake->peer_pubkey ); -#endif -} - -static void ssl_transform_init( mbedtls_ssl_transform *transform ) -{ - memset( transform, 0, sizeof(mbedtls_ssl_transform) ); - - mbedtls_cipher_init( &transform->cipher_ctx_enc ); - mbedtls_cipher_init( &transform->cipher_ctx_dec ); - - mbedtls_md_init( &transform->md_ctx_enc ); - mbedtls_md_init( &transform->md_ctx_dec ); -} - -void mbedtls_ssl_session_init( mbedtls_ssl_session *session ) -{ - memset( session, 0, sizeof(mbedtls_ssl_session) ); -} - -static int ssl_handshake_init( mbedtls_ssl_context *ssl ) -{ - /* Clear old handshake information if present */ - if( ssl->transform_negotiate ) - mbedtls_ssl_transform_free( ssl->transform_negotiate ); - if( ssl->session_negotiate ) - mbedtls_ssl_session_free( ssl->session_negotiate ); - if( ssl->handshake ) - mbedtls_ssl_handshake_free( ssl ); - - /* - * Either the pointers are now NULL or cleared properly and can be freed. - * Now allocate missing structures. - */ - if( ssl->transform_negotiate == NULL ) - { - ssl->transform_negotiate = mbedtls_calloc( 1, sizeof(mbedtls_ssl_transform) ); - } - - if( ssl->session_negotiate == NULL ) - { - ssl->session_negotiate = mbedtls_calloc( 1, sizeof(mbedtls_ssl_session) ); - } - - if( ssl->handshake == NULL ) - { - ssl->handshake = mbedtls_calloc( 1, sizeof(mbedtls_ssl_handshake_params) ); - } - - /* All pointers should exist and can be directly freed without issue */ - if( ssl->handshake == NULL || - ssl->transform_negotiate == NULL || - ssl->session_negotiate == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc() of ssl sub-contexts failed" ) ); - - mbedtls_free( ssl->handshake ); - mbedtls_free( ssl->transform_negotiate ); - mbedtls_free( ssl->session_negotiate ); - - ssl->handshake = NULL; - ssl->transform_negotiate = NULL; - ssl->session_negotiate = NULL; - - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - } - - /* Initialize structures */ - mbedtls_ssl_session_init( ssl->session_negotiate ); - ssl_transform_init( ssl->transform_negotiate ); - ssl_handshake_params_init( ssl->handshake ); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - ssl->handshake->alt_transform_out = ssl->transform_out; - - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) - ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING; - else - ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING; - - ssl_set_timer( ssl, 0 ); - } -#endif - - return( 0 ); -} - -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) -/* Dummy cookie callbacks for defaults */ -static int ssl_cookie_write_dummy( void *ctx, - unsigned char **p, unsigned char *end, - const unsigned char *cli_id, size_t cli_id_len ) -{ - ((void) ctx); - ((void) p); - ((void) end); - ((void) cli_id); - ((void) cli_id_len); - - return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); -} - -static int ssl_cookie_check_dummy( void *ctx, - const unsigned char *cookie, size_t cookie_len, - const unsigned char *cli_id, size_t cli_id_len ) -{ - ((void) ctx); - ((void) cookie); - ((void) cookie_len); - ((void) cli_id); - ((void) cli_id_len); - - return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); -} -#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */ - -/* Once ssl->out_hdr as the address of the beginning of the - * next outgoing record is set, deduce the other pointers. - * - * Note: For TLS, we save the implicit record sequence number - * (entering MAC computation) in the 8 bytes before ssl->out_hdr, - * and the caller has to make sure there's space for this. - */ - -static void ssl_update_out_pointers( mbedtls_ssl_context *ssl, - mbedtls_ssl_transform *transform ) -{ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - ssl->out_ctr = ssl->out_hdr + 3; - ssl->out_len = ssl->out_hdr + 11; - ssl->out_iv = ssl->out_hdr + 13; - } - else -#endif - { - ssl->out_ctr = ssl->out_hdr - 8; - ssl->out_len = ssl->out_hdr + 3; - ssl->out_iv = ssl->out_hdr + 5; - } - - /* Adjust out_msg to make space for explicit IV, if used. */ - if( transform != NULL && - ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) - { - ssl->out_msg = ssl->out_iv + transform->ivlen - transform->fixed_ivlen; - } - else - ssl->out_msg = ssl->out_iv; -} - -/* Once ssl->in_hdr as the address of the beginning of the - * next incoming record is set, deduce the other pointers. - * - * Note: For TLS, we save the implicit record sequence number - * (entering MAC computation) in the 8 bytes before ssl->in_hdr, - * and the caller has to make sure there's space for this. - */ - -static void ssl_update_in_pointers( mbedtls_ssl_context *ssl, - mbedtls_ssl_transform *transform ) -{ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - ssl->in_ctr = ssl->in_hdr + 3; - ssl->in_len = ssl->in_hdr + 11; - ssl->in_iv = ssl->in_hdr + 13; - } - else -#endif - { - ssl->in_ctr = ssl->in_hdr - 8; - ssl->in_len = ssl->in_hdr + 3; - ssl->in_iv = ssl->in_hdr + 5; - } - - /* Offset in_msg from in_iv to allow space for explicit IV, if used. */ - if( transform != NULL && - ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) - { - ssl->in_msg = ssl->in_iv + transform->ivlen - transform->fixed_ivlen; - } - else - ssl->in_msg = ssl->in_iv; -} - -/* - * Initialize an SSL context - */ -void mbedtls_ssl_init( mbedtls_ssl_context *ssl ) -{ - memset( ssl, 0, sizeof( mbedtls_ssl_context ) ); -} - -/* - * Setup an SSL context - */ - -static void ssl_reset_in_out_pointers( mbedtls_ssl_context *ssl ) -{ - /* Set the incoming and outgoing record pointers. */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - ssl->out_hdr = ssl->out_buf; - ssl->in_hdr = ssl->in_buf; - } - else -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - { - ssl->out_hdr = ssl->out_buf + 8; - ssl->in_hdr = ssl->in_buf + 8; - } - - /* Derive other internal pointers. */ - ssl_update_out_pointers( ssl, NULL /* no transform enabled */ ); - ssl_update_in_pointers ( ssl, NULL /* no transform enabled */ ); -} - -int mbedtls_ssl_setup( mbedtls_ssl_context *ssl, - const mbedtls_ssl_config *conf ) -{ - int ret; - - ssl->conf = conf; - - /* - * Prepare base structures - */ - - /* Set to NULL in case of an error condition */ - ssl->out_buf = NULL; - - ssl->in_buf = mbedtls_calloc( 1, MBEDTLS_SSL_IN_BUFFER_LEN ); - if( ssl->in_buf == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", MBEDTLS_SSL_IN_BUFFER_LEN) ); - ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; - goto error; - } - - ssl->out_buf = mbedtls_calloc( 1, MBEDTLS_SSL_OUT_BUFFER_LEN ); - if( ssl->out_buf == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", MBEDTLS_SSL_OUT_BUFFER_LEN) ); - ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; - goto error; - } - - ssl_reset_in_out_pointers( ssl ); - - if( ( ret = ssl_handshake_init( ssl ) ) != 0 ) - goto error; - - return( 0 ); - -error: - mbedtls_free( ssl->in_buf ); - mbedtls_free( ssl->out_buf ); - - ssl->conf = NULL; - - ssl->in_buf = NULL; - ssl->out_buf = NULL; - - ssl->in_hdr = NULL; - ssl->in_ctr = NULL; - ssl->in_len = NULL; - ssl->in_iv = NULL; - ssl->in_msg = NULL; - - ssl->out_hdr = NULL; - ssl->out_ctr = NULL; - ssl->out_len = NULL; - ssl->out_iv = NULL; - ssl->out_msg = NULL; - - return( ret ); -} - -/* - * Reset an initialized and used SSL context for re-use while retaining - * all application-set variables, function pointers and data. - * - * If partial is non-zero, keep data in the input buffer and client ID. - * (Use when a DTLS client reconnects from the same port.) - */ -static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial ) -{ - int ret; - -#if !defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) || \ - !defined(MBEDTLS_SSL_SRV_C) - ((void) partial); -#endif - - ssl->state = MBEDTLS_SSL_HELLO_REQUEST; - - /* Cancel any possibly running timer */ - ssl_set_timer( ssl, 0 ); - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - ssl->renego_status = MBEDTLS_SSL_INITIAL_HANDSHAKE; - ssl->renego_records_seen = 0; - - ssl->verify_data_len = 0; - memset( ssl->own_verify_data, 0, MBEDTLS_SSL_VERIFY_DATA_MAX_LEN ); - memset( ssl->peer_verify_data, 0, MBEDTLS_SSL_VERIFY_DATA_MAX_LEN ); -#endif - ssl->secure_renegotiation = MBEDTLS_SSL_LEGACY_RENEGOTIATION; - - ssl->in_offt = NULL; - ssl_reset_in_out_pointers( ssl ); - - ssl->in_msgtype = 0; - ssl->in_msglen = 0; -#if defined(MBEDTLS_SSL_PROTO_DTLS) - ssl->next_record_offset = 0; - ssl->in_epoch = 0; -#endif -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) - ssl_dtls_replay_reset( ssl ); -#endif - - ssl->in_hslen = 0; - ssl->nb_zero = 0; - - ssl->keep_current_message = 0; - - ssl->out_msgtype = 0; - ssl->out_msglen = 0; - ssl->out_left = 0; -#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) - if( ssl->split_done != MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED ) - ssl->split_done = 0; -#endif - - memset( ssl->cur_out_ctr, 0, sizeof( ssl->cur_out_ctr ) ); - - ssl->transform_in = NULL; - ssl->transform_out = NULL; - - ssl->session_in = NULL; - ssl->session_out = NULL; - - memset( ssl->out_buf, 0, MBEDTLS_SSL_OUT_BUFFER_LEN ); - -#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C) - if( partial == 0 ) -#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */ - { - ssl->in_left = 0; - memset( ssl->in_buf, 0, MBEDTLS_SSL_IN_BUFFER_LEN ); - } - -#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) - if( mbedtls_ssl_hw_record_reset != NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_reset()" ) ); - if( ( ret = mbedtls_ssl_hw_record_reset( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_reset", ret ); - return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); - } - } -#endif - - if( ssl->transform ) - { - mbedtls_ssl_transform_free( ssl->transform ); - mbedtls_free( ssl->transform ); - ssl->transform = NULL; - } - - if( ssl->session ) - { - mbedtls_ssl_session_free( ssl->session ); - mbedtls_free( ssl->session ); - ssl->session = NULL; - } - -#if defined(MBEDTLS_SSL_ALPN) - ssl->alpn_chosen = NULL; -#endif - -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) -#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) - if( partial == 0 ) -#endif - { - mbedtls_free( ssl->cli_id ); - ssl->cli_id = NULL; - ssl->cli_id_len = 0; - } -#endif - - if( ( ret = ssl_handshake_init( ssl ) ) != 0 ) - return( ret ); - - return( 0 ); -} - -/* - * Reset an initialized and used SSL context for re-use while retaining - * all application-set variables, function pointers and data. - */ -int mbedtls_ssl_session_reset( mbedtls_ssl_context *ssl ) -{ - return( ssl_session_reset_int( ssl, 0 ) ); -} - -/* - * SSL set accessors - */ -void mbedtls_ssl_conf_endpoint( mbedtls_ssl_config *conf, int endpoint ) -{ - conf->endpoint = endpoint; -} - -void mbedtls_ssl_conf_transport( mbedtls_ssl_config *conf, int transport ) -{ - conf->transport = transport; -} - -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) -void mbedtls_ssl_conf_dtls_anti_replay( mbedtls_ssl_config *conf, char mode ) -{ - conf->anti_replay = mode; -} -#endif - -#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) -void mbedtls_ssl_conf_dtls_badmac_limit( mbedtls_ssl_config *conf, unsigned limit ) -{ - conf->badmac_limit = limit; -} -#endif - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - -void mbedtls_ssl_set_datagram_packing( mbedtls_ssl_context *ssl, - unsigned allow_packing ) -{ - ssl->disable_datagram_packing = !allow_packing; -} - -void mbedtls_ssl_conf_handshake_timeout( mbedtls_ssl_config *conf, - uint32_t min, uint32_t max ) -{ - conf->hs_timeout_min = min; - conf->hs_timeout_max = max; -} -#endif - -void mbedtls_ssl_conf_authmode( mbedtls_ssl_config *conf, int authmode ) -{ - conf->authmode = authmode; -} - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -void mbedtls_ssl_conf_verify( mbedtls_ssl_config *conf, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy ) -{ - conf->f_vrfy = f_vrfy; - conf->p_vrfy = p_vrfy; -} -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -void mbedtls_ssl_conf_rng( mbedtls_ssl_config *conf, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - conf->f_rng = f_rng; - conf->p_rng = p_rng; -} - -void mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf, - void (*f_dbg)(void *, int, const char *, int, const char *), - void *p_dbg ) -{ - conf->f_dbg = f_dbg; - conf->p_dbg = p_dbg; -} - -void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl, - void *p_bio, - mbedtls_ssl_send_t *f_send, - mbedtls_ssl_recv_t *f_recv, - mbedtls_ssl_recv_timeout_t *f_recv_timeout ) -{ - ssl->p_bio = p_bio; - ssl->f_send = f_send; - ssl->f_recv = f_recv; - ssl->f_recv_timeout = f_recv_timeout; -} - -#if defined(MBEDTLS_SSL_PROTO_DTLS) -void mbedtls_ssl_set_mtu( mbedtls_ssl_context *ssl, uint16_t mtu ) -{ - ssl->mtu = mtu; -} -#endif - -void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout ) -{ - conf->read_timeout = timeout; -} - -void mbedtls_ssl_set_timer_cb( mbedtls_ssl_context *ssl, - void *p_timer, - mbedtls_ssl_set_timer_t *f_set_timer, - mbedtls_ssl_get_timer_t *f_get_timer ) -{ - ssl->p_timer = p_timer; - ssl->f_set_timer = f_set_timer; - ssl->f_get_timer = f_get_timer; - - /* Make sure we start with no timer running */ - ssl_set_timer( ssl, 0 ); -} - -#if defined(MBEDTLS_SSL_SRV_C) -void mbedtls_ssl_conf_session_cache( mbedtls_ssl_config *conf, - void *p_cache, - int (*f_get_cache)(void *, mbedtls_ssl_session *), - int (*f_set_cache)(void *, const mbedtls_ssl_session *) ) -{ - conf->p_cache = p_cache; - conf->f_get_cache = f_get_cache; - conf->f_set_cache = f_set_cache; -} -#endif /* MBEDTLS_SSL_SRV_C */ - -#if defined(MBEDTLS_SSL_CLI_C) -int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session *session ) -{ - int ret; - - if( ssl == NULL || - session == NULL || - ssl->session_negotiate == NULL || - ssl->conf->endpoint != MBEDTLS_SSL_IS_CLIENT ) - { - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - if( ( ret = mbedtls_ssl_session_copy( ssl->session_negotiate, - session ) ) != 0 ) - return( ret ); - - ssl->handshake->resume = 1; - - return( 0 ); -} -#endif /* MBEDTLS_SSL_CLI_C */ - -void mbedtls_ssl_conf_ciphersuites( mbedtls_ssl_config *conf, - const int *ciphersuites ) -{ - conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] = ciphersuites; - conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] = ciphersuites; - conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] = ciphersuites; - conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] = ciphersuites; -} - -void mbedtls_ssl_conf_ciphersuites_for_version( mbedtls_ssl_config *conf, - const int *ciphersuites, - int major, int minor ) -{ - if( major != MBEDTLS_SSL_MAJOR_VERSION_3 ) - return; - - if( minor < MBEDTLS_SSL_MINOR_VERSION_0 || minor > MBEDTLS_SSL_MINOR_VERSION_3 ) - return; - - conf->ciphersuite_list[minor] = ciphersuites; -} - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -void mbedtls_ssl_conf_cert_profile( mbedtls_ssl_config *conf, - const mbedtls_x509_crt_profile *profile ) -{ - conf->cert_profile = profile; -} - -/* Append a new keycert entry to a (possibly empty) list */ -static int ssl_append_key_cert( mbedtls_ssl_key_cert **head, - mbedtls_x509_crt *cert, - mbedtls_pk_context *key ) -{ - mbedtls_ssl_key_cert *new_cert; - - new_cert = mbedtls_calloc( 1, sizeof( mbedtls_ssl_key_cert ) ); - if( new_cert == NULL ) - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - - new_cert->cert = cert; - new_cert->key = key; - new_cert->next = NULL; - - /* Update head is the list was null, else add to the end */ - if( *head == NULL ) - { - *head = new_cert; - } - else - { - mbedtls_ssl_key_cert *cur = *head; - while( cur->next != NULL ) - cur = cur->next; - cur->next = new_cert; - } - - return( 0 ); -} - -int mbedtls_ssl_conf_own_cert( mbedtls_ssl_config *conf, - mbedtls_x509_crt *own_cert, - mbedtls_pk_context *pk_key ) -{ - return( ssl_append_key_cert( &conf->key_cert, own_cert, pk_key ) ); -} - -void mbedtls_ssl_conf_ca_chain( mbedtls_ssl_config *conf, - mbedtls_x509_crt *ca_chain, - mbedtls_x509_crl *ca_crl ) -{ - conf->ca_chain = ca_chain; - conf->ca_crl = ca_crl; - -#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) - /* mbedtls_ssl_conf_ca_chain() and mbedtls_ssl_conf_ca_cb() - * cannot be used together. */ - conf->f_ca_cb = NULL; - conf->p_ca_cb = NULL; -#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */ -} - -#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) -void mbedtls_ssl_conf_ca_cb( mbedtls_ssl_config *conf, - mbedtls_x509_crt_ca_cb_t f_ca_cb, - void *p_ca_cb ) -{ - conf->f_ca_cb = f_ca_cb; - conf->p_ca_cb = p_ca_cb; - - /* mbedtls_ssl_conf_ca_chain() and mbedtls_ssl_conf_ca_cb() - * cannot be used together. */ - conf->ca_chain = NULL; - conf->ca_crl = NULL; -} -#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */ -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) -int mbedtls_ssl_set_hs_own_cert( mbedtls_ssl_context *ssl, - mbedtls_x509_crt *own_cert, - mbedtls_pk_context *pk_key ) -{ - return( ssl_append_key_cert( &ssl->handshake->sni_key_cert, - own_cert, pk_key ) ); -} - -void mbedtls_ssl_set_hs_ca_chain( mbedtls_ssl_context *ssl, - mbedtls_x509_crt *ca_chain, - mbedtls_x509_crl *ca_crl ) -{ - ssl->handshake->sni_ca_chain = ca_chain; - ssl->handshake->sni_ca_crl = ca_crl; -} - -void mbedtls_ssl_set_hs_authmode( mbedtls_ssl_context *ssl, - int authmode ) -{ - ssl->handshake->sni_authmode = authmode; -} -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -void mbedtls_ssl_set_verify( mbedtls_ssl_context *ssl, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy ) -{ - ssl->f_vrfy = f_vrfy; - ssl->p_vrfy = p_vrfy; -} -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) -/* - * Set EC J-PAKE password for current handshake - */ -int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl, - const unsigned char *pw, - size_t pw_len ) -{ - mbedtls_ecjpake_role role; - - if( ssl->handshake == NULL || ssl->conf == NULL ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) - role = MBEDTLS_ECJPAKE_SERVER; - else - role = MBEDTLS_ECJPAKE_CLIENT; - - return( mbedtls_ecjpake_setup( &ssl->handshake->ecjpake_ctx, - role, - MBEDTLS_MD_SHA256, - MBEDTLS_ECP_DP_SECP256R1, - pw, pw_len ) ); -} -#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) - -static void ssl_conf_remove_psk( mbedtls_ssl_config *conf ) -{ - /* Remove reference to existing PSK, if any. */ -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if( conf->psk_opaque != 0 ) - { - /* The maintenance of the PSK key slot is the - * user's responsibility. */ - conf->psk_opaque = 0; - } - /* This and the following branch should never - * be taken simultaenously as we maintain the - * invariant that raw and opaque PSKs are never - * configured simultaneously. As a safeguard, - * though, `else` is omitted here. */ -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - if( conf->psk != NULL ) - { - mbedtls_platform_zeroize( conf->psk, conf->psk_len ); - - mbedtls_free( conf->psk ); - conf->psk = NULL; - conf->psk_len = 0; - } - - /* Remove reference to PSK identity, if any. */ - if( conf->psk_identity != NULL ) - { - mbedtls_free( conf->psk_identity ); - conf->psk_identity = NULL; - conf->psk_identity_len = 0; - } -} - -/* This function assumes that PSK identity in the SSL config is unset. - * It checks that the provided identity is well-formed and attempts - * to make a copy of it in the SSL config. - * On failure, the PSK identity in the config remains unset. */ -static int ssl_conf_set_psk_identity( mbedtls_ssl_config *conf, - unsigned char const *psk_identity, - size_t psk_identity_len ) -{ - /* Identity len will be encoded on two bytes */ - if( psk_identity == NULL || - ( psk_identity_len >> 16 ) != 0 || - psk_identity_len > MBEDTLS_SSL_OUT_CONTENT_LEN ) - { - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - conf->psk_identity = mbedtls_calloc( 1, psk_identity_len ); - if( conf->psk_identity == NULL ) - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - - conf->psk_identity_len = psk_identity_len; - memcpy( conf->psk_identity, psk_identity, conf->psk_identity_len ); - - return( 0 ); -} - -int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf, - const unsigned char *psk, size_t psk_len, - const unsigned char *psk_identity, size_t psk_identity_len ) -{ - int ret; - /* Remove opaque/raw PSK + PSK Identity */ - ssl_conf_remove_psk( conf ); - - /* Check and set raw PSK */ - if( psk == NULL || psk_len > MBEDTLS_PSK_MAX_LEN ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - if( ( conf->psk = mbedtls_calloc( 1, psk_len ) ) == NULL ) - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - conf->psk_len = psk_len; - memcpy( conf->psk, psk, conf->psk_len ); - - /* Check and set PSK Identity */ - ret = ssl_conf_set_psk_identity( conf, psk_identity, psk_identity_len ); - if( ret != 0 ) - ssl_conf_remove_psk( conf ); - - return( ret ); -} - -static void ssl_remove_psk( mbedtls_ssl_context *ssl ) -{ -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if( ssl->handshake->psk_opaque != 0 ) - { - ssl->handshake->psk_opaque = 0; - } - else -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - if( ssl->handshake->psk != NULL ) - { - mbedtls_platform_zeroize( ssl->handshake->psk, - ssl->handshake->psk_len ); - mbedtls_free( ssl->handshake->psk ); - ssl->handshake->psk_len = 0; - } -} - -int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl, - const unsigned char *psk, size_t psk_len ) -{ - if( psk == NULL || ssl->handshake == NULL ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - if( psk_len > MBEDTLS_PSK_MAX_LEN ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - ssl_remove_psk( ssl ); - - if( ( ssl->handshake->psk = mbedtls_calloc( 1, psk_len ) ) == NULL ) - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - - ssl->handshake->psk_len = psk_len; - memcpy( ssl->handshake->psk, psk, ssl->handshake->psk_len ); - - return( 0 ); -} - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -int mbedtls_ssl_conf_psk_opaque( mbedtls_ssl_config *conf, - psa_key_handle_t psk_slot, - const unsigned char *psk_identity, - size_t psk_identity_len ) -{ - int ret; - /* Clear opaque/raw PSK + PSK Identity, if present. */ - ssl_conf_remove_psk( conf ); - - /* Check and set opaque PSK */ - if( psk_slot == 0 ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - conf->psk_opaque = psk_slot; - - /* Check and set PSK Identity */ - ret = ssl_conf_set_psk_identity( conf, psk_identity, - psk_identity_len ); - if( ret != 0 ) - ssl_conf_remove_psk( conf ); - - return( ret ); -} - -int mbedtls_ssl_set_hs_psk_opaque( mbedtls_ssl_context *ssl, - psa_key_handle_t psk_slot ) -{ - if( psk_slot == 0 || ssl->handshake == NULL ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - ssl_remove_psk( ssl ); - ssl->handshake->psk_opaque = psk_slot; - return( 0 ); -} -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -void mbedtls_ssl_conf_psk_cb( mbedtls_ssl_config *conf, - int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *, - size_t), - void *p_psk ) -{ - conf->f_psk = f_psk; - conf->p_psk = p_psk; -} -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ - -#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C) - -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -int mbedtls_ssl_conf_dh_param( mbedtls_ssl_config *conf, const char *dhm_P, const char *dhm_G ) -{ - int ret; - - if( ( ret = mbedtls_mpi_read_string( &conf->dhm_P, 16, dhm_P ) ) != 0 || - ( ret = mbedtls_mpi_read_string( &conf->dhm_G, 16, dhm_G ) ) != 0 ) - { - mbedtls_mpi_free( &conf->dhm_P ); - mbedtls_mpi_free( &conf->dhm_G ); - return( ret ); - } - - return( 0 ); -} -#endif /* MBEDTLS_DEPRECATED_REMOVED */ - -int mbedtls_ssl_conf_dh_param_bin( mbedtls_ssl_config *conf, - const unsigned char *dhm_P, size_t P_len, - const unsigned char *dhm_G, size_t G_len ) -{ - int ret; - - if( ( ret = mbedtls_mpi_read_binary( &conf->dhm_P, dhm_P, P_len ) ) != 0 || - ( ret = mbedtls_mpi_read_binary( &conf->dhm_G, dhm_G, G_len ) ) != 0 ) - { - mbedtls_mpi_free( &conf->dhm_P ); - mbedtls_mpi_free( &conf->dhm_G ); - return( ret ); - } - - return( 0 ); -} - -int mbedtls_ssl_conf_dh_param_ctx( mbedtls_ssl_config *conf, mbedtls_dhm_context *dhm_ctx ) -{ - int ret; - - if( ( ret = mbedtls_mpi_copy( &conf->dhm_P, &dhm_ctx->P ) ) != 0 || - ( ret = mbedtls_mpi_copy( &conf->dhm_G, &dhm_ctx->G ) ) != 0 ) - { - mbedtls_mpi_free( &conf->dhm_P ); - mbedtls_mpi_free( &conf->dhm_G ); - return( ret ); - } - - return( 0 ); -} -#endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_SRV_C */ - -#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C) -/* - * Set the minimum length for Diffie-Hellman parameters - */ -void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf, - unsigned int bitlen ) -{ - conf->dhm_min_bitlen = bitlen; -} -#endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_CLI_C */ - -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) -/* - * Set allowed/preferred hashes for handshake signatures - */ -void mbedtls_ssl_conf_sig_hashes( mbedtls_ssl_config *conf, - const int *hashes ) -{ - conf->sig_hashes = hashes; -} -#endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ - -#if defined(MBEDTLS_ECP_C) -/* - * Set the allowed elliptic curves - */ -void mbedtls_ssl_conf_curves( mbedtls_ssl_config *conf, - const mbedtls_ecp_group_id *curve_list ) -{ - conf->curve_list = curve_list; -} -#endif /* MBEDTLS_ECP_C */ - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -int mbedtls_ssl_set_hostname( mbedtls_ssl_context *ssl, const char *hostname ) -{ - /* Initialize to suppress unnecessary compiler warning */ - size_t hostname_len = 0; - - /* Check if new hostname is valid before - * making any change to current one */ - if( hostname != NULL ) - { - hostname_len = strlen( hostname ); - - if( hostname_len > MBEDTLS_SSL_MAX_HOST_NAME_LEN ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - /* Now it's clear that we will overwrite the old hostname, - * so we can free it safely */ - - if( ssl->hostname != NULL ) - { - mbedtls_platform_zeroize( ssl->hostname, strlen( ssl->hostname ) ); - mbedtls_free( ssl->hostname ); - } - - /* Passing NULL as hostname shall clear the old one */ - - if( hostname == NULL ) - { - ssl->hostname = NULL; - } - else - { - ssl->hostname = mbedtls_calloc( 1, hostname_len + 1 ); - if( ssl->hostname == NULL ) - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - - memcpy( ssl->hostname, hostname, hostname_len ); - - ssl->hostname[hostname_len] = '\0'; - } - - return( 0 ); -} -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) -void mbedtls_ssl_conf_sni( mbedtls_ssl_config *conf, - int (*f_sni)(void *, mbedtls_ssl_context *, - const unsigned char *, size_t), - void *p_sni ) -{ - conf->f_sni = f_sni; - conf->p_sni = p_sni; -} -#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ - -#if defined(MBEDTLS_SSL_ALPN) -int mbedtls_ssl_conf_alpn_protocols( mbedtls_ssl_config *conf, const char **protos ) -{ - size_t cur_len, tot_len; - const char **p; - - /* - * RFC 7301 3.1: "Empty strings MUST NOT be included and byte strings - * MUST NOT be truncated." - * We check lengths now rather than later. - */ - tot_len = 0; - for( p = protos; *p != NULL; p++ ) - { - cur_len = strlen( *p ); - tot_len += cur_len; - - if( cur_len == 0 || cur_len > 255 || tot_len > 65535 ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - conf->alpn_list = protos; - - return( 0 ); -} - -const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl ) -{ - return( ssl->alpn_chosen ); -} -#endif /* MBEDTLS_SSL_ALPN */ - -void mbedtls_ssl_conf_max_version( mbedtls_ssl_config *conf, int major, int minor ) -{ - conf->max_major_ver = major; - conf->max_minor_ver = minor; -} - -void mbedtls_ssl_conf_min_version( mbedtls_ssl_config *conf, int major, int minor ) -{ - conf->min_major_ver = major; - conf->min_minor_ver = minor; -} - -#if defined(MBEDTLS_SSL_FALLBACK_SCSV) && defined(MBEDTLS_SSL_CLI_C) -void mbedtls_ssl_conf_fallback( mbedtls_ssl_config *conf, char fallback ) -{ - conf->fallback = fallback; -} -#endif - -#if defined(MBEDTLS_SSL_SRV_C) -void mbedtls_ssl_conf_cert_req_ca_list( mbedtls_ssl_config *conf, - char cert_req_ca_list ) -{ - conf->cert_req_ca_list = cert_req_ca_list; -} -#endif - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) -void mbedtls_ssl_conf_encrypt_then_mac( mbedtls_ssl_config *conf, char etm ) -{ - conf->encrypt_then_mac = etm; -} -#endif - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) -void mbedtls_ssl_conf_extended_master_secret( mbedtls_ssl_config *conf, char ems ) -{ - conf->extended_ms = ems; -} -#endif - -#if defined(MBEDTLS_ARC4_C) -void mbedtls_ssl_conf_arc4_support( mbedtls_ssl_config *conf, char arc4 ) -{ - conf->arc4_disabled = arc4; -} -#endif - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) -int mbedtls_ssl_conf_max_frag_len( mbedtls_ssl_config *conf, unsigned char mfl_code ) -{ - if( mfl_code >= MBEDTLS_SSL_MAX_FRAG_LEN_INVALID || - ssl_mfl_code_to_length( mfl_code ) > MBEDTLS_TLS_EXT_ADV_CONTENT_LEN ) - { - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - conf->mfl_code = mfl_code; - - return( 0 ); -} -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) -void mbedtls_ssl_conf_truncated_hmac( mbedtls_ssl_config *conf, int truncate ) -{ - conf->trunc_hmac = truncate; -} -#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ - -#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) -void mbedtls_ssl_conf_cbc_record_splitting( mbedtls_ssl_config *conf, char split ) -{ - conf->cbc_record_splitting = split; -} -#endif - -void mbedtls_ssl_conf_legacy_renegotiation( mbedtls_ssl_config *conf, int allow_legacy ) -{ - conf->allow_legacy_renegotiation = allow_legacy; -} - -#if defined(MBEDTLS_SSL_RENEGOTIATION) -void mbedtls_ssl_conf_renegotiation( mbedtls_ssl_config *conf, int renegotiation ) -{ - conf->disable_renegotiation = renegotiation; -} - -void mbedtls_ssl_conf_renegotiation_enforced( mbedtls_ssl_config *conf, int max_records ) -{ - conf->renego_max_records = max_records; -} - -void mbedtls_ssl_conf_renegotiation_period( mbedtls_ssl_config *conf, - const unsigned char period[8] ) -{ - memcpy( conf->renego_period, period, 8 ); -} -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) -#if defined(MBEDTLS_SSL_CLI_C) -void mbedtls_ssl_conf_session_tickets( mbedtls_ssl_config *conf, int use_tickets ) -{ - conf->session_tickets = use_tickets; -} -#endif - -#if defined(MBEDTLS_SSL_SRV_C) -void mbedtls_ssl_conf_session_tickets_cb( mbedtls_ssl_config *conf, - mbedtls_ssl_ticket_write_t *f_ticket_write, - mbedtls_ssl_ticket_parse_t *f_ticket_parse, - void *p_ticket ) -{ - conf->f_ticket_write = f_ticket_write; - conf->f_ticket_parse = f_ticket_parse; - conf->p_ticket = p_ticket; -} -#endif -#endif /* MBEDTLS_SSL_SESSION_TICKETS */ - -#if defined(MBEDTLS_SSL_EXPORT_KEYS) -void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf, - mbedtls_ssl_export_keys_t *f_export_keys, - void *p_export_keys ) -{ - conf->f_export_keys = f_export_keys; - conf->p_export_keys = p_export_keys; -} -#endif - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) -void mbedtls_ssl_conf_async_private_cb( - mbedtls_ssl_config *conf, - mbedtls_ssl_async_sign_t *f_async_sign, - mbedtls_ssl_async_decrypt_t *f_async_decrypt, - mbedtls_ssl_async_resume_t *f_async_resume, - mbedtls_ssl_async_cancel_t *f_async_cancel, - void *async_config_data ) -{ - conf->f_async_sign_start = f_async_sign; - conf->f_async_decrypt_start = f_async_decrypt; - conf->f_async_resume = f_async_resume; - conf->f_async_cancel = f_async_cancel; - conf->p_async_config_data = async_config_data; -} - -void *mbedtls_ssl_conf_get_async_config_data( const mbedtls_ssl_config *conf ) -{ - return( conf->p_async_config_data ); -} - -void *mbedtls_ssl_get_async_operation_data( const mbedtls_ssl_context *ssl ) -{ - if( ssl->handshake == NULL ) - return( NULL ); - else - return( ssl->handshake->user_async_ctx ); -} - -void mbedtls_ssl_set_async_operation_data( mbedtls_ssl_context *ssl, - void *ctx ) -{ - if( ssl->handshake != NULL ) - ssl->handshake->user_async_ctx = ctx; -} -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - -/* - * SSL get accessors - */ -size_t mbedtls_ssl_get_bytes_avail( const mbedtls_ssl_context *ssl ) -{ - return( ssl->in_offt == NULL ? 0 : ssl->in_msglen ); -} - -int mbedtls_ssl_check_pending( const mbedtls_ssl_context *ssl ) -{ - /* - * Case A: We're currently holding back - * a message for further processing. - */ - - if( ssl->keep_current_message == 1 ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: record held back for processing" ) ); - return( 1 ); - } - - /* - * Case B: Further records are pending in the current datagram. - */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl->in_left > ssl->next_record_offset ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: more records within current datagram" ) ); - return( 1 ); - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - - /* - * Case C: A handshake message is being processed. - */ - - if( ssl->in_hslen > 0 && ssl->in_hslen < ssl->in_msglen ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: more handshake messages within current record" ) ); - return( 1 ); - } - - /* - * Case D: An application data message is being processed - */ - if( ssl->in_offt != NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: application data record is being processed" ) ); - return( 1 ); - } - - /* - * In all other cases, the rest of the message can be dropped. - * As in ssl_get_next_record, this needs to be adapted if - * we implement support for multiple alerts in single records. - */ - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: nothing pending" ) ); - return( 0 ); -} - -uint32_t mbedtls_ssl_get_verify_result( const mbedtls_ssl_context *ssl ) -{ - if( ssl->session != NULL ) - return( ssl->session->verify_result ); - - if( ssl->session_negotiate != NULL ) - return( ssl->session_negotiate->verify_result ); - - return( 0xFFFFFFFF ); -} - -const char *mbedtls_ssl_get_ciphersuite( const mbedtls_ssl_context *ssl ) -{ - if( ssl == NULL || ssl->session == NULL ) - return( NULL ); - - return mbedtls_ssl_get_ciphersuite_name( ssl->session->ciphersuite ); -} - -const char *mbedtls_ssl_get_version( const mbedtls_ssl_context *ssl ) -{ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - switch( ssl->minor_ver ) - { - case MBEDTLS_SSL_MINOR_VERSION_2: - return( "DTLSv1.0" ); - - case MBEDTLS_SSL_MINOR_VERSION_3: - return( "DTLSv1.2" ); - - default: - return( "unknown (DTLS)" ); - } - } -#endif - - switch( ssl->minor_ver ) - { - case MBEDTLS_SSL_MINOR_VERSION_0: - return( "SSLv3.0" ); - - case MBEDTLS_SSL_MINOR_VERSION_1: - return( "TLSv1.0" ); - - case MBEDTLS_SSL_MINOR_VERSION_2: - return( "TLSv1.1" ); - - case MBEDTLS_SSL_MINOR_VERSION_3: - return( "TLSv1.2" ); - - default: - return( "unknown" ); - } -} - -int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl ) -{ - size_t transform_expansion = 0; - const mbedtls_ssl_transform *transform = ssl->transform_out; - unsigned block_size; - - if( transform == NULL ) - return( (int) mbedtls_ssl_hdr_len( ssl ) ); - -#if defined(MBEDTLS_ZLIB_SUPPORT) - if( ssl->session_out->compression != MBEDTLS_SSL_COMPRESS_NULL ) - return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); -#endif - - switch( mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_enc ) ) - { - case MBEDTLS_MODE_GCM: - case MBEDTLS_MODE_CCM: - case MBEDTLS_MODE_CHACHAPOLY: - case MBEDTLS_MODE_STREAM: - transform_expansion = transform->minlen; - break; - - case MBEDTLS_MODE_CBC: - - block_size = mbedtls_cipher_get_block_size( - &transform->cipher_ctx_enc ); - - /* Expansion due to the addition of the MAC. */ - transform_expansion += transform->maclen; - - /* Expansion due to the addition of CBC padding; - * Theoretically up to 256 bytes, but we never use - * more than the block size of the underlying cipher. */ - transform_expansion += block_size; - - /* For TLS 1.1 or higher, an explicit IV is added - * after the record header. */ -#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) - transform_expansion += block_size; -#endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */ - - break; - - default: - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - - return( (int)( mbedtls_ssl_hdr_len( ssl ) + transform_expansion ) ); -} - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) -size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl ) -{ - size_t max_len; - - /* - * Assume mfl_code is correct since it was checked when set - */ - max_len = ssl_mfl_code_to_length( ssl->conf->mfl_code ); - - /* Check if a smaller max length was negotiated */ - if( ssl->session_out != NULL && - ssl_mfl_code_to_length( ssl->session_out->mfl_code ) < max_len ) - { - max_len = ssl_mfl_code_to_length( ssl->session_out->mfl_code ); - } - - /* During a handshake, use the value being negotiated */ - if( ssl->session_negotiate != NULL && - ssl_mfl_code_to_length( ssl->session_negotiate->mfl_code ) < max_len ) - { - max_len = ssl_mfl_code_to_length( ssl->session_negotiate->mfl_code ); - } - - return( max_len ); -} -#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) -static size_t ssl_get_current_mtu( const mbedtls_ssl_context *ssl ) -{ - /* Return unlimited mtu for client hello messages to avoid fragmentation. */ - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT && - ( ssl->state == MBEDTLS_SSL_CLIENT_HELLO || - ssl->state == MBEDTLS_SSL_SERVER_HELLO ) ) - return ( 0 ); - - if( ssl->handshake == NULL || ssl->handshake->mtu == 0 ) - return( ssl->mtu ); - - if( ssl->mtu == 0 ) - return( ssl->handshake->mtu ); - - return( ssl->mtu < ssl->handshake->mtu ? - ssl->mtu : ssl->handshake->mtu ); -} -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -int mbedtls_ssl_get_max_out_record_payload( const mbedtls_ssl_context *ssl ) -{ - size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN; - -#if !defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) && \ - !defined(MBEDTLS_SSL_PROTO_DTLS) - (void) ssl; -#endif - -#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - const size_t mfl = mbedtls_ssl_get_max_frag_len( ssl ); - - if( max_len > mfl ) - max_len = mfl; -#endif - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl_get_current_mtu( ssl ) != 0 ) - { - const size_t mtu = ssl_get_current_mtu( ssl ); - const int ret = mbedtls_ssl_get_record_expansion( ssl ); - const size_t overhead = (size_t) ret; - - if( ret < 0 ) - return( ret ); - - if( mtu <= overhead ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "MTU too low for record expansion" ) ); - return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); - } - - if( max_len > mtu - overhead ) - max_len = mtu - overhead; - } -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -#if !defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) && \ - !defined(MBEDTLS_SSL_PROTO_DTLS) - ((void) ssl); -#endif - - return( (int) max_len ); -} - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -const mbedtls_x509_crt *mbedtls_ssl_get_peer_cert( const mbedtls_ssl_context *ssl ) -{ - if( ssl == NULL || ssl->session == NULL ) - return( NULL ); - -#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - return( ssl->session->peer_cert ); -#else - return( NULL ); -#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ -} -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_SSL_CLI_C) -int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl, - mbedtls_ssl_session *dst ) -{ - if( ssl == NULL || - dst == NULL || - ssl->session == NULL || - ssl->conf->endpoint != MBEDTLS_SSL_IS_CLIENT ) - { - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - - return( mbedtls_ssl_session_copy( dst, ssl->session ) ); -} -#endif /* MBEDTLS_SSL_CLI_C */ - -/* - * Perform a single step of the SSL handshake - */ -int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl ) -{ - int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - - if( ssl == NULL || ssl->conf == NULL ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_SSL_CLI_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) - ret = mbedtls_ssl_handshake_client_step( ssl ); -#endif -#if defined(MBEDTLS_SSL_SRV_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) - ret = mbedtls_ssl_handshake_server_step( ssl ); -#endif - - return( ret ); -} - -/* - * Perform the SSL handshake - */ -int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl ) -{ - int ret = 0; - - if( ssl == NULL || ssl->conf == NULL ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> handshake" ) ); - - while( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) - { - ret = mbedtls_ssl_handshake_step( ssl ); - - if( ret != 0 ) - break; - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= handshake" ) ); - - return( ret ); -} - -#if defined(MBEDTLS_SSL_RENEGOTIATION) -#if defined(MBEDTLS_SSL_SRV_C) -/* - * Write HelloRequest to request renegotiation on server - */ -static int ssl_write_hello_request( mbedtls_ssl_context *ssl ) -{ - int ret; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write hello request" ) ); - - ssl->out_msglen = 4; - ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; - ssl->out_msg[0] = MBEDTLS_SSL_HS_HELLO_REQUEST; - - if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); - return( ret ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write hello request" ) ); - - return( 0 ); -} -#endif /* MBEDTLS_SSL_SRV_C */ - -/* - * Actually renegotiate current connection, triggered by either: - * - any side: calling mbedtls_ssl_renegotiate(), - * - client: receiving a HelloRequest during mbedtls_ssl_read(), - * - server: receiving any handshake message on server during mbedtls_ssl_read() after - * the initial handshake is completed. - * If the handshake doesn't complete due to waiting for I/O, it will continue - * during the next calls to mbedtls_ssl_renegotiate() or mbedtls_ssl_read() respectively. - */ -static int ssl_start_renegotiation( mbedtls_ssl_context *ssl ) -{ - int ret; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> renegotiate" ) ); - - if( ( ret = ssl_handshake_init( ssl ) ) != 0 ) - return( ret ); - - /* RFC 6347 4.2.2: "[...] the HelloRequest will have message_seq = 0 and - * the ServerHello will have message_seq = 1" */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ) - { - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) - ssl->handshake->out_msg_seq = 1; - else - ssl->handshake->in_msg_seq = 1; - } -#endif - - ssl->state = MBEDTLS_SSL_HELLO_REQUEST; - ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS; - - if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret ); - return( ret ); - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= renegotiate" ) ); - - return( 0 ); -} - -/* - * Renegotiate current connection on client, - * or request renegotiation on server - */ -int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl ) -{ - int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - - if( ssl == NULL || ssl->conf == NULL ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_SSL_SRV_C) - /* On server, just send the request */ - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) - { - if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING; - - /* Did we already try/start sending HelloRequest? */ - if( ssl->out_left != 0 ) - return( mbedtls_ssl_flush_output( ssl ) ); - - return( ssl_write_hello_request( ssl ) ); - } -#endif /* MBEDTLS_SSL_SRV_C */ - -#if defined(MBEDTLS_SSL_CLI_C) - /* - * On client, either start the renegotiation process or, - * if already in progress, continue the handshake - */ - if( ssl->renego_status != MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) - { - if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - if( ( ret = ssl_start_renegotiation( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_start_renegotiation", ret ); - return( ret ); - } - } - else - { - if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret ); - return( ret ); - } - } -#endif /* MBEDTLS_SSL_CLI_C */ - - return( ret ); -} - -/* - * Check record counters and renegotiate if they're above the limit. - */ -static int ssl_check_ctr_renegotiate( mbedtls_ssl_context *ssl ) -{ - size_t ep_len = ssl_ep_len( ssl ); - int in_ctr_cmp; - int out_ctr_cmp; - - if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER || - ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING || - ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED ) - { - return( 0 ); - } - - in_ctr_cmp = memcmp( ssl->in_ctr + ep_len, - ssl->conf->renego_period + ep_len, 8 - ep_len ); - out_ctr_cmp = memcmp( ssl->cur_out_ctr + ep_len, - ssl->conf->renego_period + ep_len, 8 - ep_len ); - - if( in_ctr_cmp <= 0 && out_ctr_cmp <= 0 ) - { - return( 0 ); - } - - MBEDTLS_SSL_DEBUG_MSG( 1, ( "record counter limit reached: renegotiate" ) ); - return( mbedtls_ssl_renegotiate( ssl ) ); -} -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - -/* - * Receive application data decrypted from the SSL layer - */ -int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) -{ - int ret; - size_t n; - - if( ssl == NULL || ssl->conf == NULL ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read" ) ); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) - return( ret ); - - if( ssl->handshake != NULL && - ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING ) - { - if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 ) - return( ret ); - } - } -#endif - - /* - * Check if renegotiation is necessary and/or handshake is - * in process. If yes, perform/continue, and fall through - * if an unexpected packet is received while the client - * is waiting for the ServerHello. - * - * (There is no equivalent to the last condition on - * the server-side as it is not treated as within - * a handshake while waiting for the ClientHello - * after a renegotiation request.) - */ - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - ret = ssl_check_ctr_renegotiate( ssl ); - if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO && - ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret ); - return( ret ); - } -#endif - - if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) - { - ret = mbedtls_ssl_handshake( ssl ); - if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO && - ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret ); - return( ret ); - } - } - - /* Loop as long as no application data record is available */ - while( ssl->in_offt == NULL ) - { - /* Start timer if not already running */ - if( ssl->f_get_timer != NULL && - ssl->f_get_timer( ssl->p_timer ) == -1 ) - { - ssl_set_timer( ssl, ssl->conf->read_timeout ); - } - - if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) - { - if( ret == MBEDTLS_ERR_SSL_CONN_EOF ) - return( 0 ); - - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); - return( ret ); - } - - if( ssl->in_msglen == 0 && - ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA ) - { - /* - * OpenSSL sends empty messages to randomize the IV - */ - if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) - { - if( ret == MBEDTLS_ERR_SSL_CONN_EOF ) - return( 0 ); - - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); - return( ret ); - } - } - - if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "received handshake message" ) ); - - /* - * - For client-side, expect SERVER_HELLO_REQUEST. - * - For server-side, expect CLIENT_HELLO. - * - Fail (TLS) or silently drop record (DTLS) in other cases. - */ - -#if defined(MBEDTLS_SSL_CLI_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT && - ( ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_REQUEST || - ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake received (not HelloRequest)" ) ); - - /* With DTLS, drop the packet (probably from last handshake) */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - continue; - } -#endif - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } -#endif /* MBEDTLS_SSL_CLI_C */ - -#if defined(MBEDTLS_SSL_SRV_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && - ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake received (not ClientHello)" ) ); - - /* With DTLS, drop the packet (probably from last handshake) */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - continue; - } -#endif - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } -#endif /* MBEDTLS_SSL_SRV_C */ - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - /* Determine whether renegotiation attempt should be accepted */ - if( ! ( ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED || - ( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && - ssl->conf->allow_legacy_renegotiation == - MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) ) ) - { - /* - * Accept renegotiation request - */ - - /* DTLS clients need to know renego is server-initiated */ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) - { - ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING; - } -#endif - ret = ssl_start_renegotiation( ssl ); - if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO && - ret != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_start_renegotiation", ret ); - return( ret ); - } - } - else -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - { - /* - * Refuse renegotiation - */ - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "refusing renegotiation, sending alert" ) ); - -#if defined(MBEDTLS_SSL_PROTO_SSL3) - if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) - { - /* SSLv3 does not have a "no_renegotiation" warning, so - we send a fatal alert and abort the connection. */ - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } - else -#endif /* MBEDTLS_SSL_PROTO_SSL3 */ -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 ) - { - if( ( ret = mbedtls_ssl_send_alert_message( ssl, - MBEDTLS_SSL_ALERT_LEVEL_WARNING, - MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION ) ) != 0 ) - { - return( ret ); - } - } - else -#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || - MBEDTLS_SSL_PROTO_TLS1_2 */ - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); - } - } - - /* At this point, we don't know whether the renegotiation has been - * completed or not. The cases to consider are the following: - * 1) The renegotiation is complete. In this case, no new record - * has been read yet. - * 2) The renegotiation is incomplete because the client received - * an application data record while awaiting the ServerHello. - * 3) The renegotiation is incomplete because the client received - * a non-handshake, non-application data message while awaiting - * the ServerHello. - * In each of these case, looping will be the proper action: - * - For 1), the next iteration will read a new record and check - * if it's application data. - * - For 2), the loop condition isn't satisfied as application data - * is present, hence continue is the same as break - * - For 3), the loop condition is satisfied and read_record - * will re-deliver the message that was held back by the client - * when expecting the ServerHello. - */ - continue; - } -#if defined(MBEDTLS_SSL_RENEGOTIATION) - else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ) - { - if( ssl->conf->renego_max_records >= 0 ) - { - if( ++ssl->renego_records_seen > ssl->conf->renego_max_records ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation requested, " - "but not honored by client" ) ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } - } - } -#endif /* MBEDTLS_SSL_RENEGOTIATION */ - - /* Fatal and closure alerts handled by mbedtls_ssl_read_record() */ - if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "ignoring non-fatal non-closure alert" ) ); - return( MBEDTLS_ERR_SSL_WANT_READ ); - } - - if( ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad application data message" ) ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } - - ssl->in_offt = ssl->in_msg; - - /* We're going to return something now, cancel timer, - * except if handshake (renegotiation) is in progress */ - if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) - ssl_set_timer( ssl, 0 ); - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - /* If we requested renego but received AppData, resend HelloRequest. - * Do it now, after setting in_offt, to avoid taking this branch - * again if ssl_write_hello_request() returns WANT_WRITE */ -#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && - ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ) - { - if( ( ret = ssl_resend_hello_request( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_resend_hello_request", ret ); - return( ret ); - } - } -#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */ -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - } - - n = ( len < ssl->in_msglen ) - ? len : ssl->in_msglen; - - memcpy( buf, ssl->in_offt, n ); - ssl->in_msglen -= n; - - if( ssl->in_msglen == 0 ) - { - /* all bytes consumed */ - ssl->in_offt = NULL; - ssl->keep_current_message = 0; - } - else - { - /* more data available */ - ssl->in_offt += n; - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read" ) ); - - return( (int) n ); -} - -/* - * Send application data to be encrypted by the SSL layer, taking care of max - * fragment length and buffer size. - * - * According to RFC 5246 Section 6.2.1: - * - * Zero-length fragments of Application data MAY be sent as they are - * potentially useful as a traffic analysis countermeasure. - * - * Therefore, it is possible that the input message length is 0 and the - * corresponding return code is 0 on success. - */ -static int ssl_write_real( mbedtls_ssl_context *ssl, - const unsigned char *buf, size_t len ) -{ - int ret = mbedtls_ssl_get_max_out_record_payload( ssl ); - const size_t max_len = (size_t) ret; - - if( ret < 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_get_max_out_record_payload", ret ); - return( ret ); - } - - if( len > max_len ) - { -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "fragment larger than the (negotiated) " - "maximum fragment length: %d > %d", - len, max_len ) ); - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - } - else -#endif - len = max_len; - } - - if( ssl->out_left != 0 ) - { - /* - * The user has previously tried to send the data and - * MBEDTLS_ERR_SSL_WANT_WRITE or the message was only partially - * written. In this case, we expect the high-level write function - * (e.g. mbedtls_ssl_write()) to be called with the same parameters - */ - if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret ); - return( ret ); - } - } - else - { - /* - * The user is trying to send a message the first time, so we need to - * copy the data into the internal buffers and setup the data structure - * to keep track of partial writes - */ - ssl->out_msglen = len; - ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA; - memcpy( ssl->out_msg, buf, len ); - - if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); - return( ret ); - } - } - - return( (int) len ); -} - -/* - * Write application data, doing 1/n-1 splitting if necessary. - * - * With non-blocking I/O, ssl_write_real() may return WANT_WRITE, - * then the caller will call us again with the same arguments, so - * remember whether we already did the split or not. - */ -#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) -static int ssl_write_split( mbedtls_ssl_context *ssl, - const unsigned char *buf, size_t len ) -{ - int ret; - - if( ssl->conf->cbc_record_splitting == - MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED || - len <= 1 || - ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_1 || - mbedtls_cipher_get_cipher_mode( &ssl->transform_out->cipher_ctx_enc ) - != MBEDTLS_MODE_CBC ) - { - return( ssl_write_real( ssl, buf, len ) ); - } - - if( ssl->split_done == 0 ) - { - if( ( ret = ssl_write_real( ssl, buf, 1 ) ) <= 0 ) - return( ret ); - ssl->split_done = 1; - } - - if( ( ret = ssl_write_real( ssl, buf + 1, len - 1 ) ) <= 0 ) - return( ret ); - ssl->split_done = 0; - - return( ret + 1 ); -} -#endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */ - -/* - * Write application data (public-facing wrapper) - */ -int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len ) -{ - int ret; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write" ) ); - - if( ssl == NULL || ssl->conf == NULL ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ( ret = ssl_check_ctr_renegotiate( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret ); - return( ret ); - } -#endif - - if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) - { - if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret ); - return( ret ); - } - } - -#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) - ret = ssl_write_split( ssl, buf, len ); -#else - ret = ssl_write_real( ssl, buf, len ); -#endif - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write" ) ); - - return( ret ); -} - -/* - * Notify the peer that the connection is being closed - */ -int mbedtls_ssl_close_notify( mbedtls_ssl_context *ssl ) -{ - int ret; - - if( ssl == NULL || ssl->conf == NULL ) - return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write close notify" ) ); - - if( ssl->out_left != 0 ) - return( mbedtls_ssl_flush_output( ssl ) ); - - if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) - { - if( ( ret = mbedtls_ssl_send_alert_message( ssl, - MBEDTLS_SSL_ALERT_LEVEL_WARNING, - MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_send_alert_message", ret ); - return( ret ); - } - } - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write close notify" ) ); - - return( 0 ); -} - -void mbedtls_ssl_transform_free( mbedtls_ssl_transform *transform ) -{ - if( transform == NULL ) - return; - -#if defined(MBEDTLS_ZLIB_SUPPORT) - deflateEnd( &transform->ctx_deflate ); - inflateEnd( &transform->ctx_inflate ); -#endif - - mbedtls_cipher_free( &transform->cipher_ctx_enc ); - mbedtls_cipher_free( &transform->cipher_ctx_dec ); - - mbedtls_md_free( &transform->md_ctx_enc ); - mbedtls_md_free( &transform->md_ctx_dec ); - - mbedtls_platform_zeroize( transform, sizeof( mbedtls_ssl_transform ) ); -} - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -static void ssl_key_cert_free( mbedtls_ssl_key_cert *key_cert ) -{ - mbedtls_ssl_key_cert *cur = key_cert, *next; - - while( cur != NULL ) - { - next = cur->next; - mbedtls_free( cur ); - cur = next; - } -} -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - -static void ssl_buffering_free( mbedtls_ssl_context *ssl ) -{ - unsigned offset; - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - - if( hs == NULL ) - return; - - ssl_free_buffered_record( ssl ); - - for( offset = 0; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++ ) - ssl_buffering_free_slot( ssl, offset ); -} - -static void ssl_buffering_free_slot( mbedtls_ssl_context *ssl, - uint8_t slot ) -{ - mbedtls_ssl_handshake_params * const hs = ssl->handshake; - mbedtls_ssl_hs_buffer * const hs_buf = &hs->buffering.hs[slot]; - - if( slot >= MBEDTLS_SSL_MAX_BUFFERED_HS ) - return; - - if( hs_buf->is_valid == 1 ) - { - hs->buffering.total_bytes_buffered -= hs_buf->data_len; - mbedtls_platform_zeroize( hs_buf->data, hs_buf->data_len ); - mbedtls_free( hs_buf->data ); - memset( hs_buf, 0, sizeof( mbedtls_ssl_hs_buffer ) ); - } -} - -#endif /* MBEDTLS_SSL_PROTO_DTLS */ - -void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl ) -{ - mbedtls_ssl_handshake_params *handshake = ssl->handshake; - - if( handshake == NULL ) - return; - -#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) - if( ssl->conf->f_async_cancel != NULL && handshake->async_in_progress != 0 ) - { - ssl->conf->f_async_cancel( ssl ); - handshake->async_in_progress = 0; - } -#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ - -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) - mbedtls_md5_free( &handshake->fin_md5 ); - mbedtls_sha1_free( &handshake->fin_sha1 ); -#endif -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_SHA256_C) -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_hash_abort( &handshake->fin_sha256_psa ); -#else - mbedtls_sha256_free( &handshake->fin_sha256 ); -#endif -#endif -#if defined(MBEDTLS_SHA512_C) -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_hash_abort( &handshake->fin_sha384_psa ); -#else - mbedtls_sha512_free( &handshake->fin_sha512 ); -#endif -#endif -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - -#if defined(MBEDTLS_DHM_C) - mbedtls_dhm_free( &handshake->dhm_ctx ); -#endif -#if defined(MBEDTLS_ECDH_C) - mbedtls_ecdh_free( &handshake->ecdh_ctx ); -#endif -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - mbedtls_ecjpake_free( &handshake->ecjpake_ctx ); -#if defined(MBEDTLS_SSL_CLI_C) - mbedtls_free( handshake->ecjpake_cache ); - handshake->ecjpake_cache = NULL; - handshake->ecjpake_cache_len = 0; -#endif -#endif - -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - /* explicit void pointer cast for buggy MS compiler */ - mbedtls_free( (void *) handshake->curves ); -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) - if( handshake->psk != NULL ) - { - mbedtls_platform_zeroize( handshake->psk, handshake->psk_len ); - mbedtls_free( handshake->psk ); - } -#endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) && \ - defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - /* - * Free only the linked list wrapper, not the keys themselves - * since the belong to the SNI callback - */ - if( handshake->sni_key_cert != NULL ) - { - mbedtls_ssl_key_cert *cur = handshake->sni_key_cert, *next; - - while( cur != NULL ) - { - next = cur->next; - mbedtls_free( cur ); - cur = next; - } - } -#endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_SSL_SERVER_NAME_INDICATION */ - -#if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - mbedtls_x509_crt_restart_free( &handshake->ecrs_ctx ); - if( handshake->ecrs_peer_cert != NULL ) - { - mbedtls_x509_crt_free( handshake->ecrs_peer_cert ); - mbedtls_free( handshake->ecrs_peer_cert ); - } -#endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) && \ - !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) - mbedtls_pk_free( &handshake->peer_pubkey ); -#endif /* MBEDTLS_X509_CRT_PARSE_C && !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - mbedtls_free( handshake->verify_cookie ); - ssl_flight_free( handshake->flight ); - ssl_buffering_free( ssl ); -#endif - -#if defined(MBEDTLS_ECDH_C) && \ - defined(MBEDTLS_USE_PSA_CRYPTO) - psa_destroy_key( handshake->ecdh_psa_privkey ); -#endif /* MBEDTLS_ECDH_C && MBEDTLS_USE_PSA_CRYPTO */ - - mbedtls_platform_zeroize( handshake, - sizeof( mbedtls_ssl_handshake_params ) ); -} - -void mbedtls_ssl_session_free( mbedtls_ssl_session *session ) -{ - if( session == NULL ) - return; - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - ssl_clear_peer_cert( session ); -#endif - -#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) - mbedtls_free( session->ticket ); -#endif - - mbedtls_platform_zeroize( session, sizeof( mbedtls_ssl_session ) ); -} - -/* - * Free an SSL context - */ -void mbedtls_ssl_free( mbedtls_ssl_context *ssl ) -{ - if( ssl == NULL ) - return; - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> free" ) ); - - if( ssl->out_buf != NULL ) - { - mbedtls_platform_zeroize( ssl->out_buf, MBEDTLS_SSL_OUT_BUFFER_LEN ); - mbedtls_free( ssl->out_buf ); - } - - if( ssl->in_buf != NULL ) - { - mbedtls_platform_zeroize( ssl->in_buf, MBEDTLS_SSL_IN_BUFFER_LEN ); - mbedtls_free( ssl->in_buf ); - } - -#if defined(MBEDTLS_ZLIB_SUPPORT) - if( ssl->compress_buf != NULL ) - { - mbedtls_platform_zeroize( ssl->compress_buf, MBEDTLS_SSL_COMPRESS_BUFFER_LEN ); - mbedtls_free( ssl->compress_buf ); - } -#endif - - if( ssl->transform ) - { - mbedtls_ssl_transform_free( ssl->transform ); - mbedtls_free( ssl->transform ); - } - - if( ssl->handshake ) - { - mbedtls_ssl_handshake_free( ssl ); - mbedtls_ssl_transform_free( ssl->transform_negotiate ); - mbedtls_ssl_session_free( ssl->session_negotiate ); - - mbedtls_free( ssl->handshake ); - mbedtls_free( ssl->transform_negotiate ); - mbedtls_free( ssl->session_negotiate ); - } - - if( ssl->session ) - { - mbedtls_ssl_session_free( ssl->session ); - mbedtls_free( ssl->session ); - } - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - if( ssl->hostname != NULL ) - { - mbedtls_platform_zeroize( ssl->hostname, strlen( ssl->hostname ) ); - mbedtls_free( ssl->hostname ); - } -#endif - -#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) - if( mbedtls_ssl_hw_record_finish != NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_finish()" ) ); - mbedtls_ssl_hw_record_finish( ssl ); - } -#endif - -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) - mbedtls_free( ssl->cli_id ); -#endif - - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= free" ) ); - - /* Actually clear after last debug message */ - mbedtls_platform_zeroize( ssl, sizeof( mbedtls_ssl_context ) ); -} - -/* - * Initialze mbedtls_ssl_config - */ -void mbedtls_ssl_config_init( mbedtls_ssl_config *conf ) -{ - memset( conf, 0, sizeof( mbedtls_ssl_config ) ); -} - -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) -static int ssl_preset_default_hashes[] = { -#if defined(MBEDTLS_SHA512_C) - MBEDTLS_MD_SHA512, - MBEDTLS_MD_SHA384, -#endif -#if defined(MBEDTLS_SHA256_C) - MBEDTLS_MD_SHA256, - MBEDTLS_MD_SHA224, -#endif -#if defined(MBEDTLS_SHA1_C) && defined(MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE) - MBEDTLS_MD_SHA1, -#endif - MBEDTLS_MD_NONE -}; -#endif - -static int ssl_preset_suiteb_ciphersuites[] = { - MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, - MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, - 0 -}; - -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) -static int ssl_preset_suiteb_hashes[] = { - MBEDTLS_MD_SHA256, - MBEDTLS_MD_SHA384, - MBEDTLS_MD_NONE -}; -#endif - -#if defined(MBEDTLS_ECP_C) -static mbedtls_ecp_group_id ssl_preset_suiteb_curves[] = { - MBEDTLS_ECP_DP_SECP256R1, - MBEDTLS_ECP_DP_SECP384R1, - MBEDTLS_ECP_DP_NONE -}; -#endif - -/* - * Load default in mbedtls_ssl_config - */ -int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, - int endpoint, int transport, int preset ) -{ -#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C) - int ret; -#endif - - /* Use the functions here so that they are covered in tests, - * but otherwise access member directly for efficiency */ - mbedtls_ssl_conf_endpoint( conf, endpoint ); - mbedtls_ssl_conf_transport( conf, transport ); - - /* - * Things that are common to all presets - */ -#if defined(MBEDTLS_SSL_CLI_C) - if( endpoint == MBEDTLS_SSL_IS_CLIENT ) - { - conf->authmode = MBEDTLS_SSL_VERIFY_REQUIRED; -#if defined(MBEDTLS_SSL_SESSION_TICKETS) - conf->session_tickets = MBEDTLS_SSL_SESSION_TICKETS_ENABLED; -#endif - } -#endif - -#if defined(MBEDTLS_ARC4_C) - conf->arc4_disabled = MBEDTLS_SSL_ARC4_DISABLED; -#endif - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - conf->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED; -#endif - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - conf->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED; -#endif - -#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) - conf->cbc_record_splitting = MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED; -#endif - -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) - conf->f_cookie_write = ssl_cookie_write_dummy; - conf->f_cookie_check = ssl_cookie_check_dummy; -#endif - -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) - conf->anti_replay = MBEDTLS_SSL_ANTI_REPLAY_ENABLED; -#endif - -#if defined(MBEDTLS_SSL_SRV_C) - conf->cert_req_ca_list = MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED; -#endif - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - conf->hs_timeout_min = MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN; - conf->hs_timeout_max = MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MAX; -#endif - -#if defined(MBEDTLS_SSL_RENEGOTIATION) - conf->renego_max_records = MBEDTLS_SSL_RENEGO_MAX_RECORDS_DEFAULT; - memset( conf->renego_period, 0x00, 2 ); - memset( conf->renego_period + 2, 0xFF, 6 ); -#endif - -#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C) - if( endpoint == MBEDTLS_SSL_IS_SERVER ) - { - const unsigned char dhm_p[] = - MBEDTLS_DHM_RFC3526_MODP_2048_P_BIN; - const unsigned char dhm_g[] = - MBEDTLS_DHM_RFC3526_MODP_2048_G_BIN; - - if ( ( ret = mbedtls_ssl_conf_dh_param_bin( conf, - dhm_p, sizeof( dhm_p ), - dhm_g, sizeof( dhm_g ) ) ) != 0 ) - { - return( ret ); - } - } -#endif - - /* - * Preset-specific defaults - */ - switch( preset ) - { - /* - * NSA Suite B - */ - case MBEDTLS_SSL_PRESET_SUITEB: - conf->min_major_ver = MBEDTLS_SSL_MAJOR_VERSION_3; - conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_3; /* TLS 1.2 */ - conf->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION; - conf->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION; - - conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] = - conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] = - conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] = - conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] = - ssl_preset_suiteb_ciphersuites; - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - conf->cert_profile = &mbedtls_x509_crt_profile_suiteb; -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) - conf->sig_hashes = ssl_preset_suiteb_hashes; -#endif - -#if defined(MBEDTLS_ECP_C) - conf->curve_list = ssl_preset_suiteb_curves; -#endif - break; - - /* - * Default - */ - default: - conf->min_major_ver = ( MBEDTLS_SSL_MIN_MAJOR_VERSION > - MBEDTLS_SSL_MIN_VALID_MAJOR_VERSION ) ? - MBEDTLS_SSL_MIN_MAJOR_VERSION : - MBEDTLS_SSL_MIN_VALID_MAJOR_VERSION; - conf->min_minor_ver = ( MBEDTLS_SSL_MIN_MINOR_VERSION > - MBEDTLS_SSL_MIN_VALID_MINOR_VERSION ) ? - MBEDTLS_SSL_MIN_MINOR_VERSION : - MBEDTLS_SSL_MIN_VALID_MINOR_VERSION; - conf->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION; - conf->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION; - -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_2; -#endif - - conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] = - conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] = - conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] = - conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] = - mbedtls_ssl_list_ciphersuites(); - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - conf->cert_profile = &mbedtls_x509_crt_profile_default; -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) - conf->sig_hashes = ssl_preset_default_hashes; -#endif - -#if defined(MBEDTLS_ECP_C) - conf->curve_list = mbedtls_ecp_grp_id_list(); -#endif - -#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C) - conf->dhm_min_bitlen = 1024; -#endif - } - - return( 0 ); -} - -/* - * Free mbedtls_ssl_config - */ -void mbedtls_ssl_config_free( mbedtls_ssl_config *conf ) -{ -#if defined(MBEDTLS_DHM_C) - mbedtls_mpi_free( &conf->dhm_P ); - mbedtls_mpi_free( &conf->dhm_G ); -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) - if( conf->psk != NULL ) - { - mbedtls_platform_zeroize( conf->psk, conf->psk_len ); - mbedtls_free( conf->psk ); - conf->psk = NULL; - conf->psk_len = 0; - } - - if( conf->psk_identity != NULL ) - { - mbedtls_platform_zeroize( conf->psk_identity, conf->psk_identity_len ); - mbedtls_free( conf->psk_identity ); - conf->psk_identity = NULL; - conf->psk_identity_len = 0; - } -#endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - ssl_key_cert_free( conf->key_cert ); -#endif - - mbedtls_platform_zeroize( conf, sizeof( mbedtls_ssl_config ) ); -} - -#if defined(MBEDTLS_PK_C) && \ - ( defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C) ) -/* - * Convert between MBEDTLS_PK_XXX and SSL_SIG_XXX - */ -unsigned char mbedtls_ssl_sig_from_pk( mbedtls_pk_context *pk ) -{ -#if defined(MBEDTLS_RSA_C) - if( mbedtls_pk_can_do( pk, MBEDTLS_PK_RSA ) ) - return( MBEDTLS_SSL_SIG_RSA ); -#endif -#if defined(MBEDTLS_ECDSA_C) - if( mbedtls_pk_can_do( pk, MBEDTLS_PK_ECDSA ) ) - return( MBEDTLS_SSL_SIG_ECDSA ); -#endif - return( MBEDTLS_SSL_SIG_ANON ); -} - -unsigned char mbedtls_ssl_sig_from_pk_alg( mbedtls_pk_type_t type ) -{ - switch( type ) { - case MBEDTLS_PK_RSA: - return( MBEDTLS_SSL_SIG_RSA ); - case MBEDTLS_PK_ECDSA: - case MBEDTLS_PK_ECKEY: - return( MBEDTLS_SSL_SIG_ECDSA ); - default: - return( MBEDTLS_SSL_SIG_ANON ); - } -} - -mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig( unsigned char sig ) -{ - switch( sig ) - { -#if defined(MBEDTLS_RSA_C) - case MBEDTLS_SSL_SIG_RSA: - return( MBEDTLS_PK_RSA ); -#endif -#if defined(MBEDTLS_ECDSA_C) - case MBEDTLS_SSL_SIG_ECDSA: - return( MBEDTLS_PK_ECDSA ); -#endif - default: - return( MBEDTLS_PK_NONE ); - } -} -#endif /* MBEDTLS_PK_C && ( MBEDTLS_RSA_C || MBEDTLS_ECDSA_C ) */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) - -/* Find an entry in a signature-hash set matching a given hash algorithm. */ -mbedtls_md_type_t mbedtls_ssl_sig_hash_set_find( mbedtls_ssl_sig_hash_set_t *set, - mbedtls_pk_type_t sig_alg ) -{ - switch( sig_alg ) - { - case MBEDTLS_PK_RSA: - return( set->rsa ); - case MBEDTLS_PK_ECDSA: - return( set->ecdsa ); - default: - return( MBEDTLS_MD_NONE ); - } -} - -/* Add a signature-hash-pair to a signature-hash set */ -void mbedtls_ssl_sig_hash_set_add( mbedtls_ssl_sig_hash_set_t *set, - mbedtls_pk_type_t sig_alg, - mbedtls_md_type_t md_alg ) -{ - switch( sig_alg ) - { - case MBEDTLS_PK_RSA: - if( set->rsa == MBEDTLS_MD_NONE ) - set->rsa = md_alg; - break; - - case MBEDTLS_PK_ECDSA: - if( set->ecdsa == MBEDTLS_MD_NONE ) - set->ecdsa = md_alg; - break; - - default: - break; - } -} - -/* Allow exactly one hash algorithm for each signature. */ -void mbedtls_ssl_sig_hash_set_const_hash( mbedtls_ssl_sig_hash_set_t *set, - mbedtls_md_type_t md_alg ) -{ - set->rsa = md_alg; - set->ecdsa = md_alg; -} - -#endif /* MBEDTLS_SSL_PROTO_TLS1_2) && - MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ - -/* - * Convert from MBEDTLS_SSL_HASH_XXX to MBEDTLS_MD_XXX - */ -mbedtls_md_type_t mbedtls_ssl_md_alg_from_hash( unsigned char hash ) -{ - switch( hash ) - { -#if defined(MBEDTLS_MD5_C) - case MBEDTLS_SSL_HASH_MD5: - return( MBEDTLS_MD_MD5 ); -#endif -#if defined(MBEDTLS_SHA1_C) - case MBEDTLS_SSL_HASH_SHA1: - return( MBEDTLS_MD_SHA1 ); -#endif -#if defined(MBEDTLS_SHA256_C) - case MBEDTLS_SSL_HASH_SHA224: - return( MBEDTLS_MD_SHA224 ); - case MBEDTLS_SSL_HASH_SHA256: - return( MBEDTLS_MD_SHA256 ); -#endif -#if defined(MBEDTLS_SHA512_C) - case MBEDTLS_SSL_HASH_SHA384: - return( MBEDTLS_MD_SHA384 ); - case MBEDTLS_SSL_HASH_SHA512: - return( MBEDTLS_MD_SHA512 ); -#endif - default: - return( MBEDTLS_MD_NONE ); - } -} - -/* - * Convert from MBEDTLS_MD_XXX to MBEDTLS_SSL_HASH_XXX - */ -unsigned char mbedtls_ssl_hash_from_md_alg( int md ) -{ - switch( md ) - { -#if defined(MBEDTLS_MD5_C) - case MBEDTLS_MD_MD5: - return( MBEDTLS_SSL_HASH_MD5 ); -#endif -#if defined(MBEDTLS_SHA1_C) - case MBEDTLS_MD_SHA1: - return( MBEDTLS_SSL_HASH_SHA1 ); -#endif -#if defined(MBEDTLS_SHA256_C) - case MBEDTLS_MD_SHA224: - return( MBEDTLS_SSL_HASH_SHA224 ); - case MBEDTLS_MD_SHA256: - return( MBEDTLS_SSL_HASH_SHA256 ); -#endif -#if defined(MBEDTLS_SHA512_C) - case MBEDTLS_MD_SHA384: - return( MBEDTLS_SSL_HASH_SHA384 ); - case MBEDTLS_MD_SHA512: - return( MBEDTLS_SSL_HASH_SHA512 ); -#endif - default: - return( MBEDTLS_SSL_HASH_NONE ); - } -} - -#if defined(MBEDTLS_ECP_C) -/* - * Check if a curve proposed by the peer is in our list. - * Return 0 if we're willing to use it, -1 otherwise. - */ -int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id ) -{ - const mbedtls_ecp_group_id *gid; - - if( ssl->conf->curve_list == NULL ) - return( -1 ); - - for( gid = ssl->conf->curve_list; *gid != MBEDTLS_ECP_DP_NONE; gid++ ) - if( *gid == grp_id ) - return( 0 ); - - return( -1 ); -} -#endif /* MBEDTLS_ECP_C */ - -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) -/* - * Check if a hash proposed by the peer is in our list. - * Return 0 if we're willing to use it, -1 otherwise. - */ -int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl, - mbedtls_md_type_t md ) -{ - const int *cur; - - if( ssl->conf->sig_hashes == NULL ) - return( -1 ); - - for( cur = ssl->conf->sig_hashes; *cur != MBEDTLS_MD_NONE; cur++ ) - if( *cur == (int) md ) - return( 0 ); - - return( -1 ); -} -#endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ - -#if defined(MBEDTLS_X509_CRT_PARSE_C) -int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert, - const mbedtls_ssl_ciphersuite_t *ciphersuite, - int cert_endpoint, - uint32_t *flags ) -{ - int ret = 0; -#if defined(MBEDTLS_X509_CHECK_KEY_USAGE) - int usage = 0; -#endif -#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE) - const char *ext_oid; - size_t ext_len; -#endif - -#if !defined(MBEDTLS_X509_CHECK_KEY_USAGE) && \ - !defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE) - ((void) cert); - ((void) cert_endpoint); - ((void) flags); -#endif - -#if defined(MBEDTLS_X509_CHECK_KEY_USAGE) - if( cert_endpoint == MBEDTLS_SSL_IS_SERVER ) - { - /* Server part of the key exchange */ - switch( ciphersuite->key_exchange ) - { - case MBEDTLS_KEY_EXCHANGE_RSA: - case MBEDTLS_KEY_EXCHANGE_RSA_PSK: - usage = MBEDTLS_X509_KU_KEY_ENCIPHERMENT; - break; - - case MBEDTLS_KEY_EXCHANGE_DHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: - usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE; - break; - - case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: - usage = MBEDTLS_X509_KU_KEY_AGREEMENT; - break; - - /* Don't use default: we want warnings when adding new values */ - case MBEDTLS_KEY_EXCHANGE_NONE: - case MBEDTLS_KEY_EXCHANGE_PSK: - case MBEDTLS_KEY_EXCHANGE_DHE_PSK: - case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK: - case MBEDTLS_KEY_EXCHANGE_ECJPAKE: - usage = 0; - } - } - else - { - /* Client auth: we only implement rsa_sign and mbedtls_ecdsa_sign for now */ - usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE; - } - - if( mbedtls_x509_crt_check_key_usage( cert, usage ) != 0 ) - { - *flags |= MBEDTLS_X509_BADCERT_KEY_USAGE; - ret = -1; - } -#else - ((void) ciphersuite); -#endif /* MBEDTLS_X509_CHECK_KEY_USAGE */ - -#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE) - if( cert_endpoint == MBEDTLS_SSL_IS_SERVER ) - { - ext_oid = MBEDTLS_OID_SERVER_AUTH; - ext_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_SERVER_AUTH ); - } - else - { - ext_oid = MBEDTLS_OID_CLIENT_AUTH; - ext_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_CLIENT_AUTH ); - } - - if( mbedtls_x509_crt_check_extended_key_usage( cert, ext_oid, ext_len ) != 0 ) - { - *flags |= MBEDTLS_X509_BADCERT_EXT_KEY_USAGE; - ret = -1; - } -#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */ - - return( ret ); -} -#endif /* MBEDTLS_X509_CRT_PARSE_C */ - -/* - * Convert version numbers to/from wire format - * and, for DTLS, to/from TLS equivalent. - * - * For TLS this is the identity. - * For DTLS, use 1's complement (v -> 255 - v, and then map as follows: - * 1.0 <-> 3.2 (DTLS 1.0 is based on TLS 1.1) - * 1.x <-> 3.x+1 for x != 0 (DTLS 1.2 based on TLS 1.2) - */ -void mbedtls_ssl_write_version( int major, int minor, int transport, - unsigned char ver[2] ) -{ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - if( minor == MBEDTLS_SSL_MINOR_VERSION_2 ) - --minor; /* DTLS 1.0 stored as TLS 1.1 internally */ - - ver[0] = (unsigned char)( 255 - ( major - 2 ) ); - ver[1] = (unsigned char)( 255 - ( minor - 1 ) ); - } - else -#else - ((void) transport); -#endif - { - ver[0] = (unsigned char) major; - ver[1] = (unsigned char) minor; - } -} - -void mbedtls_ssl_read_version( int *major, int *minor, int transport, - const unsigned char ver[2] ) -{ -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - { - *major = 255 - ver[0] + 2; - *minor = 255 - ver[1] + 1; - - if( *minor == MBEDTLS_SSL_MINOR_VERSION_1 ) - ++*minor; /* DTLS 1.0 stored as TLS 1.1 internally */ - } - else -#else - ((void) transport); -#endif - { - *major = ver[0]; - *minor = ver[1]; - } -} - -int mbedtls_ssl_set_calc_verify_md( mbedtls_ssl_context *ssl, int md ) -{ -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 ) - return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH; - - switch( md ) - { -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) -#if defined(MBEDTLS_MD5_C) - case MBEDTLS_SSL_HASH_MD5: - return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH; -#endif -#if defined(MBEDTLS_SHA1_C) - case MBEDTLS_SSL_HASH_SHA1: - ssl->handshake->calc_verify = ssl_calc_verify_tls; - break; -#endif -#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */ -#if defined(MBEDTLS_SHA512_C) - case MBEDTLS_SSL_HASH_SHA384: - ssl->handshake->calc_verify = ssl_calc_verify_tls_sha384; - break; -#endif -#if defined(MBEDTLS_SHA256_C) - case MBEDTLS_SSL_HASH_SHA256: - ssl->handshake->calc_verify = ssl_calc_verify_tls_sha256; - break; -#endif - default: - return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH; - } - - return 0; -#else /* !MBEDTLS_SSL_PROTO_TLS1_2 */ - (void) ssl; - (void) md; - - return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH; -#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ -} - -#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) -int mbedtls_ssl_get_key_exchange_md_ssl_tls( mbedtls_ssl_context *ssl, - unsigned char *output, - unsigned char *data, size_t data_len ) -{ - int ret = 0; - mbedtls_md5_context mbedtls_md5; - mbedtls_sha1_context mbedtls_sha1; - - mbedtls_md5_init( &mbedtls_md5 ); - mbedtls_sha1_init( &mbedtls_sha1 ); - - /* - * digitally-signed struct { - * opaque md5_hash[16]; - * opaque sha_hash[20]; - * }; - * - * md5_hash - * MD5(ClientHello.random + ServerHello.random - * + ServerParams); - * sha_hash - * SHA(ClientHello.random + ServerHello.random - * + ServerParams); - */ - if( ( ret = mbedtls_md5_starts_ret( &mbedtls_md5 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md5_starts_ret", ret ); - goto exit; - } - if( ( ret = mbedtls_md5_update_ret( &mbedtls_md5, - ssl->handshake->randbytes, 64 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md5_update_ret", ret ); - goto exit; - } - if( ( ret = mbedtls_md5_update_ret( &mbedtls_md5, data, data_len ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md5_update_ret", ret ); - goto exit; - } - if( ( ret = mbedtls_md5_finish_ret( &mbedtls_md5, output ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md5_finish_ret", ret ); - goto exit; - } - - if( ( ret = mbedtls_sha1_starts_ret( &mbedtls_sha1 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_sha1_starts_ret", ret ); - goto exit; - } - if( ( ret = mbedtls_sha1_update_ret( &mbedtls_sha1, - ssl->handshake->randbytes, 64 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_sha1_update_ret", ret ); - goto exit; - } - if( ( ret = mbedtls_sha1_update_ret( &mbedtls_sha1, data, - data_len ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_sha1_update_ret", ret ); - goto exit; - } - if( ( ret = mbedtls_sha1_finish_ret( &mbedtls_sha1, - output + 16 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_sha1_finish_ret", ret ); - goto exit; - } - -exit: - mbedtls_md5_free( &mbedtls_md5 ); - mbedtls_sha1_free( &mbedtls_sha1 ); - - if( ret != 0 ) - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); - - return( ret ); - -} -#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \ - MBEDTLS_SSL_PROTO_TLS1_1 */ - -#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl, - unsigned char *hash, size_t *hashlen, - unsigned char *data, size_t data_len, - mbedtls_md_type_t md_alg ) -{ - psa_status_t status; - psa_hash_operation_t hash_operation = PSA_HASH_OPERATION_INIT; - psa_algorithm_t hash_alg = mbedtls_psa_translate_md( md_alg ); - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "Perform PSA-based computation of digest of ServerKeyExchange" ) ); - - if( ( status = psa_hash_setup( &hash_operation, - hash_alg ) ) != PSA_SUCCESS ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "psa_hash_setup", status ); - goto exit; - } - - if( ( status = psa_hash_update( &hash_operation, ssl->handshake->randbytes, - 64 ) ) != PSA_SUCCESS ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "psa_hash_update", status ); - goto exit; - } - - if( ( status = psa_hash_update( &hash_operation, - data, data_len ) ) != PSA_SUCCESS ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "psa_hash_update", status ); - goto exit; - } - - if( ( status = psa_hash_finish( &hash_operation, hash, MBEDTLS_MD_MAX_SIZE, - hashlen ) ) != PSA_SUCCESS ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "psa_hash_finish", status ); - goto exit; - } - -exit: - if( status != PSA_SUCCESS ) - { - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); - switch( status ) - { - case PSA_ERROR_NOT_SUPPORTED: - return( MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE ); - case PSA_ERROR_BAD_STATE: /* Intentional fallthrough */ - case PSA_ERROR_BUFFER_TOO_SMALL: - return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); - case PSA_ERROR_INSUFFICIENT_MEMORY: - return( MBEDTLS_ERR_MD_ALLOC_FAILED ); - default: - return( MBEDTLS_ERR_MD_HW_ACCEL_FAILED ); - } - } - return( 0 ); -} - -#else - -int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl, - unsigned char *hash, size_t *hashlen, - unsigned char *data, size_t data_len, - mbedtls_md_type_t md_alg ) -{ - int ret = 0; - mbedtls_md_context_t ctx; - const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg ); - *hashlen = mbedtls_md_get_size( md_info ); - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "Perform mbedtls-based computation of digest of ServerKeyExchange" ) ); - - mbedtls_md_init( &ctx ); - - /* - * digitally-signed struct { - * opaque client_random[32]; - * opaque server_random[32]; - * ServerDHParams params; - * }; - */ - if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret ); - goto exit; - } - if( ( ret = mbedtls_md_starts( &ctx ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_starts", ret ); - goto exit; - } - if( ( ret = mbedtls_md_update( &ctx, ssl->handshake->randbytes, 64 ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_update", ret ); - goto exit; - } - if( ( ret = mbedtls_md_update( &ctx, data, data_len ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_update", ret ); - goto exit; - } - if( ( ret = mbedtls_md_finish( &ctx, hash ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_finish", ret ); - goto exit; - } - -exit: - mbedtls_md_free( &ctx ); - - if( ret != 0 ) - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); - - return( ret ); -} -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ - MBEDTLS_SSL_PROTO_TLS1_2 */ - -#endif /* MBEDTLS_SSL_TLS_C */ diff --git a/library/x509.c b/library/x509.c deleted file mode 100644 index 3f8e29071..000000000 --- a/library/x509.c +++ /dev/null @@ -1,1062 +0,0 @@ -/* - * X.509 common functions for parsing and verification - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -/* - * 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 - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_X509_USE_C) - -#include "mbedtls/x509.h" -#include "mbedtls/asn1.h" -#include "mbedtls/oid.h" - -#include -#include - -#if defined(MBEDTLS_PEM_PARSE_C) -#include "mbedtls/pem.h" -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#include -#define mbedtls_free free -#define mbedtls_calloc calloc -#define mbedtls_printf printf -#define mbedtls_snprintf snprintf -#endif - -#if defined(MBEDTLS_HAVE_TIME) -#include "mbedtls/platform_time.h" -#endif -#if defined(MBEDTLS_HAVE_TIME_DATE) -#include "mbedtls/platform_util.h" -#include -#endif - -#define CHECK(code) if( ( ret = code ) != 0 ){ return( ret ); } -#define CHECK_RANGE(min, max, val) if( val < min || val > max ){ return( ret ); } - -/* - * CertificateSerialNumber ::= INTEGER - */ -int mbedtls_x509_get_serial( unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *serial ) -{ - int ret; - - if( ( end - *p ) < 1 ) - return( MBEDTLS_ERR_X509_INVALID_SERIAL + - MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - if( **p != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_PRIMITIVE | 2 ) && - **p != MBEDTLS_ASN1_INTEGER ) - return( MBEDTLS_ERR_X509_INVALID_SERIAL + - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); - - serial->tag = *(*p)++; - - if( ( ret = mbedtls_asn1_get_len( p, end, &serial->len ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_SERIAL + ret ); - - serial->p = *p; - *p += serial->len; - - return( 0 ); -} - -/* Get an algorithm identifier without parameters (eg for signatures) - * - * AlgorithmIdentifier ::= SEQUENCE { - * algorithm OBJECT IDENTIFIER, - * parameters ANY DEFINED BY algorithm OPTIONAL } - */ -int mbedtls_x509_get_alg_null( unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *alg ) -{ - int ret; - - if( ( ret = mbedtls_asn1_get_alg_null( p, end, alg ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); - - return( 0 ); -} - -/* - * Parse an algorithm identifier with (optional) parameters - */ -int mbedtls_x509_get_alg( unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *alg, mbedtls_x509_buf *params ) -{ - int ret; - - if( ( ret = mbedtls_asn1_get_alg( p, end, alg, params ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); - - return( 0 ); -} - -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) -/* - * HashAlgorithm ::= AlgorithmIdentifier - * - * AlgorithmIdentifier ::= SEQUENCE { - * algorithm OBJECT IDENTIFIER, - * parameters ANY DEFINED BY algorithm OPTIONAL } - * - * For HashAlgorithm, parameters MUST be NULL or absent. - */ -static int x509_get_hash_alg( const mbedtls_x509_buf *alg, mbedtls_md_type_t *md_alg ) -{ - int ret; - unsigned char *p; - const unsigned char *end; - mbedtls_x509_buf md_oid; - size_t len; - - /* Make sure we got a SEQUENCE and setup bounds */ - if( alg->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) - return( MBEDTLS_ERR_X509_INVALID_ALG + - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); - - p = (unsigned char *) alg->p; - end = p + alg->len; - - if( p >= end ) - return( MBEDTLS_ERR_X509_INVALID_ALG + - MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - /* Parse md_oid */ - md_oid.tag = *p; - - if( ( ret = mbedtls_asn1_get_tag( &p, end, &md_oid.len, MBEDTLS_ASN1_OID ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); - - md_oid.p = p; - p += md_oid.len; - - /* Get md_alg from md_oid */ - if( ( ret = mbedtls_oid_get_md_alg( &md_oid, md_alg ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); - - /* Make sure params is absent of NULL */ - if( p == end ) - return( 0 ); - - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_NULL ) ) != 0 || len != 0 ) - return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); - - if( p != end ) - return( MBEDTLS_ERR_X509_INVALID_ALG + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - return( 0 ); -} - -/* - * RSASSA-PSS-params ::= SEQUENCE { - * hashAlgorithm [0] HashAlgorithm DEFAULT sha1Identifier, - * maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1Identifier, - * saltLength [2] INTEGER DEFAULT 20, - * trailerField [3] INTEGER DEFAULT 1 } - * -- Note that the tags in this Sequence are explicit. - * - * RFC 4055 (which defines use of RSASSA-PSS in PKIX) states that the value - * of trailerField MUST be 1, and PKCS#1 v2.2 doesn't even define any other - * option. Enfore this at parsing time. - */ -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 ) -{ - int ret; - unsigned char *p; - const unsigned char *end, *end2; - size_t len; - mbedtls_x509_buf alg_id, alg_params; - - /* First set everything to defaults */ - *md_alg = MBEDTLS_MD_SHA1; - *mgf_md = MBEDTLS_MD_SHA1; - *salt_len = 20; - - /* Make sure params is a SEQUENCE and setup bounds */ - if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) - return( MBEDTLS_ERR_X509_INVALID_ALG + - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); - - p = (unsigned char *) params->p; - end = p + params->len; - - if( p == end ) - return( 0 ); - - /* - * HashAlgorithm - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) == 0 ) - { - end2 = p + len; - - /* HashAlgorithm ::= AlgorithmIdentifier (without parameters) */ - if( ( ret = mbedtls_x509_get_alg_null( &p, end2, &alg_id ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_oid_get_md_alg( &alg_id, md_alg ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); - - if( p != end2 ) - return( MBEDTLS_ERR_X509_INVALID_ALG + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - } - else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) - return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); - - if( p == end ) - return( 0 ); - - /* - * MaskGenAlgorithm - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) ) == 0 ) - { - end2 = p + len; - - /* MaskGenAlgorithm ::= AlgorithmIdentifier (params = HashAlgorithm) */ - if( ( ret = mbedtls_x509_get_alg( &p, end2, &alg_id, &alg_params ) ) != 0 ) - return( ret ); - - /* Only MFG1 is recognised for now */ - if( MBEDTLS_OID_CMP( MBEDTLS_OID_MGF1, &alg_id ) != 0 ) - return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE + - MBEDTLS_ERR_OID_NOT_FOUND ); - - /* Parse HashAlgorithm */ - if( ( ret = x509_get_hash_alg( &alg_params, mgf_md ) ) != 0 ) - return( ret ); - - if( p != end2 ) - return( MBEDTLS_ERR_X509_INVALID_ALG + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - } - else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) - return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); - - if( p == end ) - return( 0 ); - - /* - * salt_len - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 2 ) ) == 0 ) - { - end2 = p + len; - - if( ( ret = mbedtls_asn1_get_int( &p, end2, salt_len ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); - - if( p != end2 ) - return( MBEDTLS_ERR_X509_INVALID_ALG + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - } - else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) - return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); - - if( p == end ) - return( 0 ); - - /* - * trailer_field (if present, must be 1) - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 3 ) ) == 0 ) - { - int trailer_field; - - end2 = p + len; - - if( ( ret = mbedtls_asn1_get_int( &p, end2, &trailer_field ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); - - if( p != end2 ) - return( MBEDTLS_ERR_X509_INVALID_ALG + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - if( trailer_field != 1 ) - return( MBEDTLS_ERR_X509_INVALID_ALG ); - } - else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) - return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); - - if( p != end ) - return( MBEDTLS_ERR_X509_INVALID_ALG + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - return( 0 ); -} -#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ - -/* - * AttributeTypeAndValue ::= SEQUENCE { - * type AttributeType, - * value AttributeValue } - * - * AttributeType ::= OBJECT IDENTIFIER - * - * AttributeValue ::= ANY DEFINED BY AttributeType - */ -static int x509_get_attr_type_value( unsigned char **p, - const unsigned char *end, - mbedtls_x509_name *cur ) -{ - int ret; - size_t len; - mbedtls_x509_buf *oid; - mbedtls_x509_buf *val; - - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_NAME + ret ); - - if( ( end - *p ) < 1 ) - return( MBEDTLS_ERR_X509_INVALID_NAME + - MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - oid = &cur->oid; - oid->tag = **p; - - if( ( ret = mbedtls_asn1_get_tag( p, end, &oid->len, MBEDTLS_ASN1_OID ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_NAME + ret ); - - oid->p = *p; - *p += oid->len; - - if( ( end - *p ) < 1 ) - return( MBEDTLS_ERR_X509_INVALID_NAME + - MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - if( **p != MBEDTLS_ASN1_BMP_STRING && **p != MBEDTLS_ASN1_UTF8_STRING && - **p != MBEDTLS_ASN1_T61_STRING && **p != MBEDTLS_ASN1_PRINTABLE_STRING && - **p != MBEDTLS_ASN1_IA5_STRING && **p != MBEDTLS_ASN1_UNIVERSAL_STRING && - **p != MBEDTLS_ASN1_BIT_STRING ) - return( MBEDTLS_ERR_X509_INVALID_NAME + - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); - - val = &cur->val; - val->tag = *(*p)++; - - if( ( ret = mbedtls_asn1_get_len( p, end, &val->len ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_NAME + ret ); - - val->p = *p; - *p += val->len; - - cur->next = NULL; - - return( 0 ); -} - -/* - * Name ::= CHOICE { -- only one possibility for now -- - * rdnSequence RDNSequence } - * - * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName - * - * RelativeDistinguishedName ::= - * SET OF AttributeTypeAndValue - * - * AttributeTypeAndValue ::= SEQUENCE { - * type AttributeType, - * value AttributeValue } - * - * AttributeType ::= OBJECT IDENTIFIER - * - * AttributeValue ::= ANY DEFINED BY AttributeType - * - * The data structure is optimized for the common case where each RDN has only - * one element, which is represented as a list of AttributeTypeAndValue. - * For the general case we still use a flat list, but we mark elements of the - * same set so that they are "merged" together in the functions that consume - * this list, eg mbedtls_x509_dn_gets(). - */ -int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end, - mbedtls_x509_name *cur ) -{ - int ret; - size_t set_len; - const unsigned char *end_set; - - /* don't use recursion, we'd risk stack overflow if not optimized */ - while( 1 ) - { - /* - * parse SET - */ - if( ( ret = mbedtls_asn1_get_tag( p, end, &set_len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_NAME + ret ); - - end_set = *p + set_len; - - while( 1 ) - { - if( ( ret = x509_get_attr_type_value( p, end_set, cur ) ) != 0 ) - return( ret ); - - if( *p == end_set ) - break; - - /* Mark this item as being no the only one in a set */ - cur->next_merged = 1; - - cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) ); - - if( cur->next == NULL ) - return( MBEDTLS_ERR_X509_ALLOC_FAILED ); - - cur = cur->next; - } - - /* - * continue until end of SEQUENCE is reached - */ - if( *p == end ) - return( 0 ); - - cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) ); - - if( cur->next == NULL ) - return( MBEDTLS_ERR_X509_ALLOC_FAILED ); - - cur = cur->next; - } -} - -static int x509_parse_int( unsigned char **p, size_t n, int *res ) -{ - *res = 0; - - for( ; n > 0; --n ) - { - if( ( **p < '0') || ( **p > '9' ) ) - return ( MBEDTLS_ERR_X509_INVALID_DATE ); - - *res *= 10; - *res += ( *(*p)++ - '0' ); - } - - return( 0 ); -} - -static int x509_date_is_valid(const mbedtls_x509_time *t ) -{ - int ret = MBEDTLS_ERR_X509_INVALID_DATE; - int month_len; - - CHECK_RANGE( 0, 9999, t->year ); - CHECK_RANGE( 0, 23, t->hour ); - CHECK_RANGE( 0, 59, t->min ); - CHECK_RANGE( 0, 59, t->sec ); - - switch( t->mon ) - { - case 1: case 3: case 5: case 7: case 8: case 10: case 12: - month_len = 31; - break; - case 4: case 6: case 9: case 11: - month_len = 30; - break; - case 2: - if( ( !( t->year % 4 ) && t->year % 100 ) || - !( t->year % 400 ) ) - month_len = 29; - else - month_len = 28; - break; - default: - return( ret ); - } - CHECK_RANGE( 1, month_len, t->day ); - - return( 0 ); -} - -/* - * Parse an ASN1_UTC_TIME (yearlen=2) or ASN1_GENERALIZED_TIME (yearlen=4) - * field. - */ -static int x509_parse_time( unsigned char **p, size_t len, size_t yearlen, - mbedtls_x509_time *tm ) -{ - int ret; - - /* - * Minimum length is 10 or 12 depending on yearlen - */ - if ( len < yearlen + 8 ) - return ( MBEDTLS_ERR_X509_INVALID_DATE ); - len -= yearlen + 8; - - /* - * Parse year, month, day, hour, minute - */ - CHECK( x509_parse_int( p, yearlen, &tm->year ) ); - if ( 2 == yearlen ) - { - if ( tm->year < 50 ) - tm->year += 100; - - tm->year += 1900; - } - - CHECK( x509_parse_int( p, 2, &tm->mon ) ); - CHECK( x509_parse_int( p, 2, &tm->day ) ); - CHECK( x509_parse_int( p, 2, &tm->hour ) ); - CHECK( x509_parse_int( p, 2, &tm->min ) ); - - /* - * Parse seconds if present - */ - if ( len >= 2 ) - { - CHECK( x509_parse_int( p, 2, &tm->sec ) ); - len -= 2; - } - else - return ( MBEDTLS_ERR_X509_INVALID_DATE ); - - /* - * Parse trailing 'Z' if present - */ - if ( 1 == len && 'Z' == **p ) - { - (*p)++; - len--; - } - - /* - * We should have parsed all characters at this point - */ - if ( 0 != len ) - return ( MBEDTLS_ERR_X509_INVALID_DATE ); - - CHECK( x509_date_is_valid( tm ) ); - - return ( 0 ); -} - -/* - * Time ::= CHOICE { - * utcTime UTCTime, - * generalTime GeneralizedTime } - */ -int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end, - mbedtls_x509_time *tm ) -{ - int ret; - size_t len, year_len; - unsigned char tag; - - if( ( end - *p ) < 1 ) - return( MBEDTLS_ERR_X509_INVALID_DATE + - MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - tag = **p; - - if( tag == MBEDTLS_ASN1_UTC_TIME ) - year_len = 2; - else if( tag == MBEDTLS_ASN1_GENERALIZED_TIME ) - year_len = 4; - else - return( MBEDTLS_ERR_X509_INVALID_DATE + - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); - - (*p)++; - ret = mbedtls_asn1_get_len( p, end, &len ); - - if( ret != 0 ) - return( MBEDTLS_ERR_X509_INVALID_DATE + ret ); - - return x509_parse_time( p, len, year_len, tm ); -} - -int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig ) -{ - int ret; - size_t len; - int tag_type; - - if( ( end - *p ) < 1 ) - return( MBEDTLS_ERR_X509_INVALID_SIGNATURE + - MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - tag_type = **p; - - if( ( ret = mbedtls_asn1_get_bitstring_null( p, end, &len ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_SIGNATURE + ret ); - - sig->tag = tag_type; - sig->len = len; - sig->p = *p; - - *p += len; - - return( 0 ); -} - -/* - * Get signature algorithm from alg OID and optional parameters - */ -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_type_t *pk_alg, - void **sig_opts ) -{ - int ret; - - if( *sig_opts != NULL ) - return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); - - if( ( ret = mbedtls_oid_get_sig_alg( sig_oid, md_alg, pk_alg ) ) != 0 ) - return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + ret ); - -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) - if( *pk_alg == MBEDTLS_PK_RSASSA_PSS ) - { - mbedtls_pk_rsassa_pss_options *pss_opts; - - pss_opts = mbedtls_calloc( 1, sizeof( mbedtls_pk_rsassa_pss_options ) ); - if( pss_opts == NULL ) - return( MBEDTLS_ERR_X509_ALLOC_FAILED ); - - ret = mbedtls_x509_get_rsassa_pss_params( sig_params, - md_alg, - &pss_opts->mgf1_hash_id, - &pss_opts->expected_salt_len ); - if( ret != 0 ) - { - mbedtls_free( pss_opts ); - return( ret ); - } - - *sig_opts = (void *) pss_opts; - } - else -#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ - { - /* Make sure parameters are absent or NULL */ - if( ( sig_params->tag != MBEDTLS_ASN1_NULL && sig_params->tag != 0 ) || - sig_params->len != 0 ) - return( MBEDTLS_ERR_X509_INVALID_ALG ); - } - - return( 0 ); -} - -/* - * X.509 Extensions (No parsing of extensions, pointer should - * be either manually updated or extensions should be parsed!) - */ -int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *ext, int tag ) -{ - int ret; - size_t len; - - if( *p == end ) - return( 0 ); - - ext->tag = **p; - - if( ( ret = mbedtls_asn1_get_tag( p, end, &ext->len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag ) ) != 0 ) - return( ret ); - - ext->p = *p; - end = *p + ext->len; - - /* - * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension - * - * Extension ::= SEQUENCE { - * extnID OBJECT IDENTIFIER, - * critical BOOLEAN DEFAULT FALSE, - * extnValue OCTET STRING } - */ - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - - if( end != *p + len ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - return( 0 ); -} - -/* - * Store the name in printable form into buf; no more - * than size characters will be written - */ -int mbedtls_x509_dn_gets( char *buf, size_t size, const mbedtls_x509_name *dn ) -{ - int ret; - size_t i, n; - unsigned char c, merge = 0; - const mbedtls_x509_name *name; - const char *short_name = NULL; - char s[MBEDTLS_X509_MAX_DN_NAME_SIZE], *p; - - memset( s, 0, sizeof( s ) ); - - name = dn; - p = buf; - n = size; - - while( name != NULL ) - { - if( !name->oid.p ) - { - name = name->next; - continue; - } - - if( name != dn ) - { - ret = mbedtls_snprintf( p, n, merge ? " + " : ", " ); - MBEDTLS_X509_SAFE_SNPRINTF; - } - - ret = mbedtls_oid_get_attr_short_name( &name->oid, &short_name ); - - if( ret == 0 ) - ret = mbedtls_snprintf( p, n, "%s=", short_name ); - else - ret = mbedtls_snprintf( p, n, "\?\?=" ); - MBEDTLS_X509_SAFE_SNPRINTF; - - for( i = 0; i < name->val.len; i++ ) - { - if( i >= sizeof( s ) - 1 ) - break; - - c = name->val.p[i]; - if( c < 32 || c == 127 || ( c > 128 && c < 160 ) ) - s[i] = '?'; - else s[i] = c; - } - s[i] = '\0'; - ret = mbedtls_snprintf( p, n, "%s", s ); - MBEDTLS_X509_SAFE_SNPRINTF; - - merge = name->next_merged; - name = name->next; - } - - return( (int) ( size - n ) ); -} - -/* - * Store the serial in printable form into buf; no more - * than size characters will be written - */ -int mbedtls_x509_serial_gets( char *buf, size_t size, const mbedtls_x509_buf *serial ) -{ - int ret; - size_t i, n, nr; - char *p; - - p = buf; - n = size; - - nr = ( serial->len <= 32 ) - ? serial->len : 28; - - for( i = 0; i < nr; i++ ) - { - if( i == 0 && nr > 1 && serial->p[i] == 0x0 ) - continue; - - ret = mbedtls_snprintf( p, n, "%02X%s", - serial->p[i], ( i < nr - 1 ) ? ":" : "" ); - MBEDTLS_X509_SAFE_SNPRINTF; - } - - if( nr != serial->len ) - { - ret = mbedtls_snprintf( p, n, "...." ); - MBEDTLS_X509_SAFE_SNPRINTF; - } - - return( (int) ( size - n ) ); -} - -/* - * Helper for writing signature algorithms - */ -int mbedtls_x509_sig_alg_gets( char *buf, size_t size, const mbedtls_x509_buf *sig_oid, - mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg, - const void *sig_opts ) -{ - int ret; - char *p = buf; - size_t n = size; - const char *desc = NULL; - - ret = mbedtls_oid_get_sig_alg_desc( sig_oid, &desc ); - if( ret != 0 ) - ret = mbedtls_snprintf( p, n, "???" ); - else - ret = mbedtls_snprintf( p, n, "%s", desc ); - MBEDTLS_X509_SAFE_SNPRINTF; - -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) - if( pk_alg == MBEDTLS_PK_RSASSA_PSS ) - { - const mbedtls_pk_rsassa_pss_options *pss_opts; - const mbedtls_md_info_t *md_info, *mgf_md_info; - - pss_opts = (const mbedtls_pk_rsassa_pss_options *) sig_opts; - - md_info = mbedtls_md_info_from_type( md_alg ); - mgf_md_info = mbedtls_md_info_from_type( pss_opts->mgf1_hash_id ); - - ret = mbedtls_snprintf( p, n, " (%s, MGF1-%s, 0x%02X)", - md_info ? mbedtls_md_get_name( md_info ) : "???", - mgf_md_info ? mbedtls_md_get_name( mgf_md_info ) : "???", - pss_opts->expected_salt_len ); - MBEDTLS_X509_SAFE_SNPRINTF; - } -#else - ((void) pk_alg); - ((void) md_alg); - ((void) sig_opts); -#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ - - return( (int)( size - n ) ); -} - -/* - * Helper for writing "RSA key size", "EC key size", etc - */ -int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char *name ) -{ - char *p = buf; - size_t n = buf_size; - int ret; - - ret = mbedtls_snprintf( p, n, "%s key size", name ); - MBEDTLS_X509_SAFE_SNPRINTF; - - return( 0 ); -} - -#if defined(MBEDTLS_HAVE_TIME_DATE) -/* - * Set the time structure to the current time. - * Return 0 on success, non-zero on failure. - */ -static int x509_get_current_time( mbedtls_x509_time *now ) -{ - struct tm *lt, tm_buf; - mbedtls_time_t tt; - int ret = 0; - - tt = mbedtls_time( NULL ); - lt = mbedtls_platform_gmtime_r( &tt, &tm_buf ); - - if( lt == NULL ) - ret = -1; - else - { - now->year = lt->tm_year + 1900; - now->mon = lt->tm_mon + 1; - now->day = lt->tm_mday; - now->hour = lt->tm_hour; - now->min = lt->tm_min; - now->sec = lt->tm_sec; - } - - return( ret ); -} - -/* - * Return 0 if before <= after, 1 otherwise - */ -static int x509_check_time( const mbedtls_x509_time *before, const mbedtls_x509_time *after ) -{ - if( before->year > after->year ) - return( 1 ); - - if( before->year == after->year && - before->mon > after->mon ) - return( 1 ); - - if( before->year == after->year && - before->mon == after->mon && - before->day > after->day ) - return( 1 ); - - if( before->year == after->year && - before->mon == after->mon && - before->day == after->day && - before->hour > after->hour ) - return( 1 ); - - if( before->year == after->year && - before->mon == after->mon && - before->day == after->day && - before->hour == after->hour && - before->min > after->min ) - return( 1 ); - - if( before->year == after->year && - before->mon == after->mon && - before->day == after->day && - before->hour == after->hour && - before->min == after->min && - before->sec > after->sec ) - return( 1 ); - - return( 0 ); -} - -int mbedtls_x509_time_is_past( const mbedtls_x509_time *to ) -{ - mbedtls_x509_time now; - - if( x509_get_current_time( &now ) != 0 ) - return( 1 ); - - return( x509_check_time( &now, to ) ); -} - -int mbedtls_x509_time_is_future( const mbedtls_x509_time *from ) -{ - mbedtls_x509_time now; - - if( x509_get_current_time( &now ) != 0 ) - return( 1 ); - - return( x509_check_time( from, &now ) ); -} - -#else /* MBEDTLS_HAVE_TIME_DATE */ - -int mbedtls_x509_time_is_past( const mbedtls_x509_time *to ) -{ - ((void) to); - return( 0 ); -} - -int mbedtls_x509_time_is_future( const mbedtls_x509_time *from ) -{ - ((void) from); - return( 0 ); -} -#endif /* MBEDTLS_HAVE_TIME_DATE */ - -#if defined(MBEDTLS_SELF_TEST) - -#include "mbedtls/x509_crt.h" -#include "mbedtls/certs.h" - -/* - * Checkup routine - */ -int mbedtls_x509_self_test( int verbose ) -{ - int ret = 0; -#if defined(MBEDTLS_CERTS_C) && defined(MBEDTLS_SHA256_C) - uint32_t flags; - mbedtls_x509_crt cacert; - mbedtls_x509_crt clicert; - - if( verbose != 0 ) - mbedtls_printf( " X.509 certificate load: " ); - - mbedtls_x509_crt_init( &cacert ); - mbedtls_x509_crt_init( &clicert ); - - ret = mbedtls_x509_crt_parse( &clicert, (const unsigned char *) mbedtls_test_cli_crt, - mbedtls_test_cli_crt_len ); - if( ret != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - goto cleanup; - } - - ret = mbedtls_x509_crt_parse( &cacert, (const unsigned char *) mbedtls_test_ca_crt, - mbedtls_test_ca_crt_len ); - if( ret != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - goto cleanup; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n X.509 signature verify: "); - - ret = mbedtls_x509_crt_verify( &clicert, &cacert, NULL, NULL, &flags, NULL, NULL ); - if( ret != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - goto cleanup; - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n\n"); - -cleanup: - mbedtls_x509_crt_free( &cacert ); - mbedtls_x509_crt_free( &clicert ); -#else - ((void) verbose); -#endif /* MBEDTLS_CERTS_C && MBEDTLS_SHA1_C */ - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_X509_USE_C */ diff --git a/library/x509_create.c b/library/x509_create.c deleted file mode 100644 index 546e8fa1a..000000000 --- a/library/x509_create.c +++ /dev/null @@ -1,379 +0,0 @@ -/* - * X.509 base functions for creating certificates / CSRs - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_X509_CREATE_C) - -#include "mbedtls/x509.h" -#include "mbedtls/asn1write.h" -#include "mbedtls/oid.h" - -#include - -/* 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. */ - 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 ); -} - -int mbedtls_x509_string_to_names( mbedtls_asn1_named_data **head, const char *name ) -{ - int ret = 0; - const char *s = name, *c = s; - const char *end = s + strlen( s ); - const char *oid = NULL; - const x509_attr_descriptor_t* attr_descr = NULL; - int in_tag = 1; - char data[MBEDTLS_X509_MAX_DN_NAME_SIZE]; - char *d = data; - - /* Clear existing chain if present */ - mbedtls_asn1_free_named_data_list( head ); - - while( c <= end ) - { - if( in_tag && *c == '=' ) - { - if( ( attr_descr = x509_attr_descr_from_name( s, c - s ) ) == NULL ) - { - ret = MBEDTLS_ERR_X509_UNKNOWN_OID; - goto exit; - } - - oid = attr_descr->oid; - s = c + 1; - in_tag = 0; - d = data; - } - - if( !in_tag && *c == '\\' && c != end ) - { - c++; - - /* Check for valid escaped characters */ - if( c == end || *c != ',' ) - { - ret = MBEDTLS_ERR_X509_INVALID_NAME; - goto exit; - } - } - else if( !in_tag && ( *c == ',' || c == end ) ) - { - mbedtls_asn1_named_data* cur = - mbedtls_asn1_store_named_data( head, oid, strlen( oid ), - (unsigned char *) data, - d - data ); - - if(cur == NULL ) - { - return( MBEDTLS_ERR_X509_ALLOC_FAILED ); - } - - // set tagType - cur->val.tag = attr_descr->default_tag; - - while( c < end && *(c + 1) == ' ' ) - c++; - - s = c + 1; - in_tag = 1; - } - - if( !in_tag && s != c + 1 ) - { - *(d++) = *c; - - if( d - data == MBEDTLS_X509_MAX_DN_NAME_SIZE ) - { - ret = MBEDTLS_ERR_X509_INVALID_NAME; - goto exit; - } - } - - c++; - } - -exit: - - 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( ( 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; - 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; - 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 ) -{ - int ret; - 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 - // - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( p, start, oid, - oid_len, 0 ) ); - - return( (int) len ); -} - -static int x509_write_extension( unsigned char **p, unsigned char *start, - mbedtls_asn1_named_data *ext ) -{ - int ret; - 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; - 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 */ diff --git a/library/x509_crl.c b/library/x509_crl.c deleted file mode 100644 index 8450f87e0..000000000 --- a/library/x509_crl.c +++ /dev/null @@ -1,773 +0,0 @@ -/* - * X.509 Certidicate Revocation List (CRL) parsing - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -/* - * 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 - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_X509_CRL_PARSE_C) - -#include "mbedtls/x509_crl.h" -#include "mbedtls/oid.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_PEM_PARSE_C) -#include "mbedtls/pem.h" -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#include -#define mbedtls_free free -#define mbedtls_calloc calloc -#define mbedtls_snprintf snprintf -#endif - -#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) -#include -#else -#include -#endif - -#if defined(MBEDTLS_FS_IO) || defined(EFIX64) || defined(EFI32) -#include -#endif - -/* - * Version ::= INTEGER { v1(0), v2(1) } - */ -static int x509_crl_get_version( unsigned char **p, - const unsigned char *end, - int *ver ) -{ - int ret; - - if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 ) - { - if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) - { - *ver = 0; - return( 0 ); - } - - return( 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; - - /* - * crlExtensions [0] EXPLICIT Extensions OPTIONAL - * -- if present, version MUST be v2 - */ - if( ( ret = mbedtls_x509_get_ext( p, end, ext, 0 ) ) != 0 ) - { - if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) - return( 0 ); - - return( ret ); - } - - 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_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_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_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_ERR_X509_INVALID_EXTENSIONS + ret ); - - /* Ignore data so far and just check its length */ - *p += len; - if( *p != end_ext_data ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - /* Abort on (unsupported) critical extensions */ - if( is_critical ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); - } - - if( *p != end ) - return( 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; - 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_ERR_X509_INVALID_EXTENSIONS + ret ); - } - - end = *p + ext->len; - - if( end != *p + ext->len ) - return( 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_ERR_X509_INVALID_EXTENSIONS + ret ); - - *p += len; - } - - if( *p != end ) - return( 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; - 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; - - if( ( ret = mbedtls_asn1_get_tag( p, end, &len2, - MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED ) ) != 0 ) - { - return( ret ); - } - - cur_entry->raw.tag = **p; - 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; - 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_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_ERR_X509_INVALID_FORMAT + ret ); - } - - end = p + len; - crl->tbs.len = 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, - &crl->sig_opts ) ) != 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_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 = 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_ERR_X509_INVALID_DATE + - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) && - ret != ( 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_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_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; - size_t use_len; - 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; - 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_platform_zeroize( buf, n ); - mbedtls_free( buf ); - - return( ret ); -} -#endif /* MBEDTLS_FS_IO */ - -/* - * Return an informational string about the certificate. - */ -#define BEFORE_COLON 14 -#define BC "14" -/* - * 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; - 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, - crl->sig_opts ); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_snprintf( p, n, "\n" ); - MBEDTLS_X509_SAFE_SNPRINTF; - - return( (int) ( size - n ) ); -} - -/* - * 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_name *name_cur; - mbedtls_x509_name *name_prv; - mbedtls_x509_crl_entry *entry_cur; - mbedtls_x509_crl_entry *entry_prv; - - if( crl == NULL ) - return; - - do - { -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) - mbedtls_free( crl_cur->sig_opts ); -#endif - - name_cur = crl_cur->issuer.next; - while( name_cur != NULL ) - { - name_prv = name_cur; - name_cur = name_cur->next; - mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) ); - mbedtls_free( name_prv ); - } - - entry_cur = crl_cur->entry.next; - while( entry_cur != NULL ) - { - entry_prv = entry_cur; - entry_cur = entry_cur->next; - mbedtls_platform_zeroize( entry_prv, - sizeof( mbedtls_x509_crl_entry ) ); - mbedtls_free( entry_prv ); - } - - if( crl_cur->raw.p != NULL ) - { - mbedtls_platform_zeroize( crl_cur->raw.p, crl_cur->raw.len ); - mbedtls_free( crl_cur->raw.p ); - } - - crl_cur = crl_cur->next; - } - while( crl_cur != NULL ); - - crl_cur = crl; - do - { - 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 ); - } - while( crl_cur != NULL ); -} - -#endif /* MBEDTLS_X509_CRL_PARSE_C */ diff --git a/library/x509_crt.c b/library/x509_crt.c deleted file mode 100644 index 605d8efd8..000000000 --- a/library/x509_crt.c +++ /dev/null @@ -1,2879 +0,0 @@ -/* - * X.509 certificate parsing and verification - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -/* - * 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 - * - * [SIRO] https://cabforum.org/wp-content/uploads/Chunghwatelecom201503cabforumV4.pdf - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) - -#include "mbedtls/x509_crt.h" -#include "mbedtls/oid.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_PEM_PARSE_C) -#include "mbedtls/pem.h" -#endif - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "psa/crypto.h" -#include "mbedtls/psa_util.h" -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#include -#define mbedtls_free free -#define mbedtls_calloc calloc -#define mbedtls_snprintf snprintf -#endif - -#if defined(MBEDTLS_THREADING_C) -#include "mbedtls/threading.h" -#endif - -#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) -#include -#else -#include -#endif - -#if defined(MBEDTLS_FS_IO) -#include -#if !defined(_WIN32) || defined(EFIX64) || defined(EFI32) -#include -#include -#include -#endif /* !_WIN32 || EFIX64 || EFI32 */ -#endif - -/* - * Item in a verification chain: cert and flags for it - */ -typedef struct { - mbedtls_x509_crt *crt; - uint32_t flags; -} x509_crt_verify_chain_item; - -/* - * Max size of verification chain: end-entity + intermediates + trusted root - */ -#define X509_MAX_VERIFY_CHAIN_SIZE ( MBEDTLS_X509_MAX_INTERMEDIATE_CA + 2 ) - -/* - * Default profile - */ -const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default = -{ -#if defined(MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES) - /* Allow SHA-1 (weak, but still safe in controlled environments) */ - MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 ) | -#endif - /* Only SHA-2 hashes */ - MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224 ) | - MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) | - MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) | - MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ), - 0xFFFFFFF, /* Any PK alg */ - 0xFFFFFFF, /* Any curve */ - 2048, -}; - -/* - * Next-default profile - */ -const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_next = -{ - /* Hashes from SHA-256 and above */ - MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) | - MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) | - MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ), - 0xFFFFFFF, /* Any PK alg */ -#if defined(MBEDTLS_ECP_C) - /* Curves at or above 128-bit security level */ - MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) | - MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ) | - MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP521R1 ) | - MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP256R1 ) | - MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP384R1 ) | - MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP512R1 ) | - MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256K1 ), -#else - 0, -#endif - 2048, -}; - -/* - * NSA Suite B Profile - */ -const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb = -{ - /* Only SHA-256 and 384 */ - MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) | - MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ), - /* Only ECDSA */ - MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECDSA ) | - MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECKEY ), -#if defined(MBEDTLS_ECP_C) - /* Only NIST P-256 and P-384 */ - MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) | - MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ), -#else - 0, -#endif - 0, -}; - -/* - * Check md_alg against profile - * Return 0 if md_alg is acceptable for this profile, -1 otherwise - */ -static int x509_profile_check_md_alg( const mbedtls_x509_crt_profile *profile, - mbedtls_md_type_t md_alg ) -{ - if( md_alg == MBEDTLS_MD_NONE ) - return( -1 ); - - if( ( profile->allowed_mds & MBEDTLS_X509_ID_FLAG( md_alg ) ) != 0 ) - return( 0 ); - - return( -1 ); -} - -/* - * Check pk_alg against profile - * Return 0 if pk_alg is acceptable for this profile, -1 otherwise - */ -static int x509_profile_check_pk_alg( const mbedtls_x509_crt_profile *profile, - mbedtls_pk_type_t pk_alg ) -{ - if( pk_alg == MBEDTLS_PK_NONE ) - return( -1 ); - - if( ( profile->allowed_pks & MBEDTLS_X509_ID_FLAG( pk_alg ) ) != 0 ) - return( 0 ); - - return( -1 ); -} - -/* - * Check key against profile - * Return 0 if pk is acceptable for this profile, -1 otherwise - */ -static int x509_profile_check_key( const mbedtls_x509_crt_profile *profile, - const mbedtls_pk_context *pk ) -{ - const mbedtls_pk_type_t pk_alg = mbedtls_pk_get_type( pk ); - -#if defined(MBEDTLS_RSA_C) - if( pk_alg == MBEDTLS_PK_RSA || pk_alg == MBEDTLS_PK_RSASSA_PSS ) - { - if( mbedtls_pk_get_bitlen( pk ) >= profile->rsa_min_bitlen ) - return( 0 ); - - return( -1 ); - } -#endif - -#if defined(MBEDTLS_ECP_C) - if( pk_alg == MBEDTLS_PK_ECDSA || - pk_alg == MBEDTLS_PK_ECKEY || - pk_alg == MBEDTLS_PK_ECKEY_DH ) - { - const mbedtls_ecp_group_id gid = mbedtls_pk_ec( *pk )->grp.id; - - if( gid == MBEDTLS_ECP_DP_NONE ) - return( -1 ); - - if( ( profile->allowed_curves & MBEDTLS_X509_ID_FLAG( gid ) ) != 0 ) - return( 0 ); - - return( -1 ); - } -#endif - - return( -1 ); -} - -/* - * Like memcmp, but case-insensitive and always returns -1 if different - */ -static int x509_memcasecmp( const void *s1, const void *s2, size_t len ) -{ - size_t i; - unsigned char diff; - const unsigned char *n1 = s1, *n2 = s2; - - for( i = 0; i < len; i++ ) - { - diff = n1[i] ^ n2[i]; - - if( diff == 0 ) - continue; - - if( diff == 32 && - ( ( n1[i] >= 'a' && n1[i] <= 'z' ) || - ( n1[i] >= 'A' && n1[i] <= 'Z' ) ) ) - { - continue; - } - - return( -1 ); - } - - return( 0 ); -} - -/* - * Return 0 if name matches wildcard, -1 otherwise - */ -static int x509_check_wildcard( const char *cn, const mbedtls_x509_buf *name ) -{ - size_t i; - size_t cn_idx = 0, cn_len = strlen( cn ); - - /* We can't have a match if there is no wildcard to match */ - if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' ) - return( -1 ); - - for( i = 0; i < cn_len; ++i ) - { - if( cn[i] == '.' ) - { - cn_idx = i; - break; - } - } - - if( cn_idx == 0 ) - return( -1 ); - - if( cn_len - cn_idx == name->len - 1 && - x509_memcasecmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 ) - { - return( 0 ); - } - - return( -1 ); -} - -/* - * Compare two X.509 strings, case-insensitive, and allowing for some encoding - * variations (but not all). - * - * Return 0 if equal, -1 otherwise. - */ -static int x509_string_cmp( const mbedtls_x509_buf *a, const mbedtls_x509_buf *b ) -{ - if( a->tag == b->tag && - a->len == b->len && - memcmp( a->p, b->p, b->len ) == 0 ) - { - return( 0 ); - } - - if( ( a->tag == MBEDTLS_ASN1_UTF8_STRING || a->tag == MBEDTLS_ASN1_PRINTABLE_STRING ) && - ( b->tag == MBEDTLS_ASN1_UTF8_STRING || b->tag == MBEDTLS_ASN1_PRINTABLE_STRING ) && - a->len == b->len && - x509_memcasecmp( a->p, b->p, b->len ) == 0 ) - { - return( 0 ); - } - - return( -1 ); -} - -/* - * Compare two X.509 Names (aka rdnSequence). - * - * See RFC 5280 section 7.1, though we don't implement the whole algorithm: - * we sometimes return unequal when the full algorithm would return equal, - * but never the other way. (In particular, we don't do Unicode normalisation - * or space folding.) - * - * Return 0 if equal, -1 otherwise. - */ -static int x509_name_cmp( const mbedtls_x509_name *a, const mbedtls_x509_name *b ) -{ - /* Avoid recursion, it might not be optimised by the compiler */ - while( a != NULL || b != NULL ) - { - if( a == NULL || b == NULL ) - return( -1 ); - - /* type */ - if( a->oid.tag != b->oid.tag || - a->oid.len != b->oid.len || - memcmp( a->oid.p, b->oid.p, b->oid.len ) != 0 ) - { - return( -1 ); - } - - /* value */ - if( x509_string_cmp( &a->val, &b->val ) != 0 ) - return( -1 ); - - /* structure of the list of sets */ - if( a->next_merged != b->next_merged ) - return( -1 ); - - a = a->next; - b = b->next; - } - - /* a == NULL == b */ - return( 0 ); -} - -/* - * Reset (init or clear) a verify_chain - */ -static void x509_crt_verify_chain_reset( - mbedtls_x509_crt_verify_chain *ver_chain ) -{ - size_t i; - - for( i = 0; i < MBEDTLS_X509_MAX_VERIFY_CHAIN_SIZE; i++ ) - { - ver_chain->items[i].crt = NULL; - ver_chain->items[i].flags = (uint32_t) -1; - } - - ver_chain->len = 0; - -#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) - ver_chain->trust_ca_cb_result = NULL; -#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */ -} - -/* - * Version ::= INTEGER { v1(0), v2(1), v3(2) } - */ -static int x509_get_version( unsigned char **p, - const unsigned char *end, - int *ver ) -{ - int ret; - size_t len; - - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) != 0 ) - { - if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) - { - *ver = 0; - return( 0 ); - } - - return( ret ); - } - - end = *p + len; - - if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_VERSION + ret ); - - if( *p != end ) - return( MBEDTLS_ERR_X509_INVALID_VERSION + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - return( 0 ); -} - -/* - * Validity ::= SEQUENCE { - * notBefore Time, - * notAfter Time } - */ -static int x509_get_dates( unsigned char **p, - const unsigned char *end, - mbedtls_x509_time *from, - mbedtls_x509_time *to ) -{ - int ret; - size_t len; - - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_DATE + ret ); - - end = *p + len; - - if( ( ret = mbedtls_x509_get_time( p, end, from ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_x509_get_time( p, end, to ) ) != 0 ) - return( ret ); - - if( *p != end ) - return( MBEDTLS_ERR_X509_INVALID_DATE + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - return( 0 ); -} - -/* - * X.509 v2/v3 unique identifier (not parsed) - */ -static int x509_get_uid( unsigned char **p, - const unsigned char *end, - mbedtls_x509_buf *uid, int n ) -{ - int ret; - - if( *p == end ) - return( 0 ); - - uid->tag = **p; - - if( ( ret = mbedtls_asn1_get_tag( p, end, &uid->len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | n ) ) != 0 ) - { - if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) - return( 0 ); - - return( ret ); - } - - uid->p = *p; - *p += uid->len; - - return( 0 ); -} - -static int x509_get_basic_constraints( unsigned char **p, - const unsigned char *end, - int *ca_istrue, - int *max_pathlen ) -{ - int ret; - size_t len; - - /* - * BasicConstraints ::= SEQUENCE { - * cA BOOLEAN DEFAULT FALSE, - * pathLenConstraint INTEGER (0..MAX) OPTIONAL } - */ - *ca_istrue = 0; /* DEFAULT FALSE */ - *max_pathlen = 0; /* endless */ - - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - - if( *p == end ) - return( 0 ); - - if( ( ret = mbedtls_asn1_get_bool( p, end, ca_istrue ) ) != 0 ) - { - if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) - ret = mbedtls_asn1_get_int( p, end, ca_istrue ); - - if( ret != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - - if( *ca_istrue != 0 ) - *ca_istrue = 1; - } - - if( *p == end ) - return( 0 ); - - if( ( ret = mbedtls_asn1_get_int( p, end, max_pathlen ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - - if( *p != end ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - (*max_pathlen)++; - - return( 0 ); -} - -static int x509_get_ns_cert_type( unsigned char **p, - const unsigned char *end, - unsigned char *ns_cert_type) -{ - int ret; - mbedtls_x509_bitstring bs = { 0, 0, NULL }; - - if( ( ret = mbedtls_asn1_get_bitstring( p, end, &bs ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - - if( bs.len != 1 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_INVALID_LENGTH ); - - /* Get actual bitstring */ - *ns_cert_type = *bs.p; - return( 0 ); -} - -static int x509_get_key_usage( unsigned char **p, - const unsigned char *end, - unsigned int *key_usage) -{ - int ret; - size_t i; - mbedtls_x509_bitstring bs = { 0, 0, NULL }; - - if( ( ret = mbedtls_asn1_get_bitstring( p, end, &bs ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - - if( bs.len < 1 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_INVALID_LENGTH ); - - /* Get actual bitstring */ - *key_usage = 0; - for( i = 0; i < bs.len && i < sizeof( unsigned int ); i++ ) - { - *key_usage |= (unsigned int) bs.p[i] << (8*i); - } - - return( 0 ); -} - -/* - * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId - * - * KeyPurposeId ::= OBJECT IDENTIFIER - */ -static int x509_get_ext_key_usage( unsigned char **p, - const unsigned char *end, - mbedtls_x509_sequence *ext_key_usage) -{ - int ret; - - if( ( ret = mbedtls_asn1_get_sequence_of( p, end, ext_key_usage, MBEDTLS_ASN1_OID ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - - /* Sequence length must be >= 1 */ - if( ext_key_usage->buf.p == NULL ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_INVALID_LENGTH ); - - return( 0 ); -} - -/* - * SubjectAltName ::= GeneralNames - * - * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName - * - * GeneralName ::= CHOICE { - * otherName [0] OtherName, - * rfc822Name [1] IA5String, - * dNSName [2] IA5String, - * x400Address [3] ORAddress, - * directoryName [4] Name, - * ediPartyName [5] EDIPartyName, - * uniformResourceIdentifier [6] IA5String, - * iPAddress [7] OCTET STRING, - * registeredID [8] OBJECT IDENTIFIER } - * - * OtherName ::= SEQUENCE { - * type-id OBJECT IDENTIFIER, - * value [0] EXPLICIT ANY DEFINED BY type-id } - * - * EDIPartyName ::= SEQUENCE { - * nameAssigner [0] DirectoryString OPTIONAL, - * partyName [1] DirectoryString } - * - * NOTE: we only parse and use dNSName at this point. - */ -static int x509_get_subject_alt_name( unsigned char **p, - const unsigned char *end, - mbedtls_x509_sequence *subject_alt_name ) -{ - int ret; - size_t len, tag_len; - mbedtls_asn1_buf *buf; - unsigned char tag; - mbedtls_asn1_sequence *cur = subject_alt_name; - - /* Get main sequence tag */ - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - - if( *p + len != end ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - while( *p < end ) - { - if( ( end - *p ) < 1 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - tag = **p; - (*p)++; - if( ( ret = mbedtls_asn1_get_len( p, end, &tag_len ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - - if( ( tag & MBEDTLS_ASN1_TAG_CLASS_MASK ) != - MBEDTLS_ASN1_CONTEXT_SPECIFIC ) - { - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); - } - - /* Skip everything but DNS name */ - if( tag != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | 2 ) ) - { - *p += tag_len; - continue; - } - - /* Allocate and assign next pointer */ - if( cur->buf.p != NULL ) - { - if( cur->next != NULL ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS ); - - cur->next = mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence ) ); - - if( cur->next == NULL ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_ALLOC_FAILED ); - - cur = cur->next; - } - - buf = &(cur->buf); - buf->tag = tag; - buf->p = *p; - buf->len = tag_len; - *p += buf->len; - } - - /* Set final sequence entry's next pointer to NULL */ - cur->next = NULL; - - if( *p != end ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - return( 0 ); -} - -/* - * X.509 v3 extensions - * - */ -static int x509_get_crt_ext( unsigned char **p, - const unsigned char *end, - mbedtls_x509_crt *crt ) -{ - int ret; - size_t len; - unsigned char *end_ext_data, *end_ext_octet; - - if( ( ret = mbedtls_x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 ) - { - if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) - return( 0 ); - - return( ret ); - } - - while( *p < end ) - { - /* - * Extension ::= SEQUENCE { - * extnID OBJECT IDENTIFIER, - * critical BOOLEAN DEFAULT FALSE, - * extnValue OCTET STRING } - */ - mbedtls_x509_buf extn_oid = {0, 0, NULL}; - int is_critical = 0; /* DEFAULT FALSE */ - int ext_type = 0; - - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - return( 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_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_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_ERR_X509_INVALID_EXTENSIONS + ret ); - - end_ext_octet = *p + len; - - if( end_ext_octet != end_ext_data ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - /* - * Detect supported extensions - */ - ret = mbedtls_oid_get_x509_ext_type( &extn_oid, &ext_type ); - - if( ret != 0 ) - { - /* No parser found, skip extension */ - *p = end_ext_octet; - -#if !defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION) - if( is_critical ) - { - /* Data is marked as critical: fail */ - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); - } -#endif - continue; - } - - /* Forbid repeated extensions */ - if( ( crt->ext_types & ext_type ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS ); - - crt->ext_types |= ext_type; - - switch( ext_type ) - { - case MBEDTLS_X509_EXT_BASIC_CONSTRAINTS: - /* Parse basic constraints */ - if( ( ret = x509_get_basic_constraints( p, end_ext_octet, - &crt->ca_istrue, &crt->max_pathlen ) ) != 0 ) - return( ret ); - break; - - case MBEDTLS_X509_EXT_KEY_USAGE: - /* Parse key usage */ - if( ( ret = x509_get_key_usage( p, end_ext_octet, - &crt->key_usage ) ) != 0 ) - return( ret ); - break; - - case MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE: - /* Parse extended key usage */ - if( ( ret = x509_get_ext_key_usage( p, end_ext_octet, - &crt->ext_key_usage ) ) != 0 ) - return( ret ); - break; - - case MBEDTLS_X509_EXT_SUBJECT_ALT_NAME: - /* Parse subject alt name */ - if( ( ret = x509_get_subject_alt_name( p, end_ext_octet, - &crt->subject_alt_names ) ) != 0 ) - return( ret ); - break; - - case MBEDTLS_X509_EXT_NS_CERT_TYPE: - /* Parse netscape certificate type */ - if( ( ret = x509_get_ns_cert_type( p, end_ext_octet, - &crt->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 !defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION) - if( is_critical ) - return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE ); - else -#endif - *p = end_ext_octet; - } - } - - if( *p != end ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - return( 0 ); -} - -/* - * Parse and fill a single X.509 certificate in DER format - */ -static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, - const unsigned char *buf, - size_t buflen, - int make_copy ) -{ - int ret; - size_t len; - unsigned char *p, *end, *crt_end; - mbedtls_x509_buf sig_params1, sig_params2, sig_oid2; - - memset( &sig_params1, 0, sizeof( mbedtls_x509_buf ) ); - memset( &sig_params2, 0, sizeof( mbedtls_x509_buf ) ); - memset( &sig_oid2, 0, sizeof( mbedtls_x509_buf ) ); - - /* - * Check for valid input - */ - if( crt == NULL || buf == NULL ) - return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); - - /* Use the original buffer until we figure out actual length. */ - p = (unsigned char*) buf; - len = buflen; - end = p + len; - - /* - * Certificate ::= SEQUENCE { - * tbsCertificate TBSCertificate, - * signatureAlgorithm AlgorithmIdentifier, - * signatureValue BIT STRING } - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( MBEDTLS_ERR_X509_INVALID_FORMAT ); - } - - end = crt_end = p + len; - crt->raw.len = crt_end - buf; - if( make_copy != 0 ) - { - /* Create and populate a new buffer for the raw field. */ - crt->raw.p = p = mbedtls_calloc( 1, crt->raw.len ); - if( crt->raw.p == NULL ) - return( MBEDTLS_ERR_X509_ALLOC_FAILED ); - - memcpy( crt->raw.p, buf, crt->raw.len ); - crt->own_buffer = 1; - - p += crt->raw.len - len; - end = crt_end = p + len; - } - else - { - crt->raw.p = (unsigned char*) buf; - crt->own_buffer = 0; - } - - /* - * TBSCertificate ::= SEQUENCE { - */ - crt->tbs.p = p; - - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); - } - - end = p + len; - crt->tbs.len = end - crt->tbs.p; - - /* - * Version ::= INTEGER { v1(0), v2(1), v3(2) } - * - * CertificateSerialNumber ::= INTEGER - * - * signature AlgorithmIdentifier - */ - if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 || - ( ret = mbedtls_x509_get_serial( &p, end, &crt->serial ) ) != 0 || - ( ret = mbedtls_x509_get_alg( &p, end, &crt->sig_oid, - &sig_params1 ) ) != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( ret ); - } - - if( crt->version < 0 || crt->version > 2 ) - { - mbedtls_x509_crt_free( crt ); - return( MBEDTLS_ERR_X509_UNKNOWN_VERSION ); - } - - crt->version++; - - if( ( ret = mbedtls_x509_get_sig_alg( &crt->sig_oid, &sig_params1, - &crt->sig_md, &crt->sig_pk, - &crt->sig_opts ) ) != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( ret ); - } - - /* - * issuer Name - */ - crt->issuer_raw.p = p; - - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); - } - - if( ( ret = mbedtls_x509_get_name( &p, p + len, &crt->issuer ) ) != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( ret ); - } - - crt->issuer_raw.len = p - crt->issuer_raw.p; - - /* - * Validity ::= SEQUENCE { - * notBefore Time, - * notAfter Time } - * - */ - if( ( ret = x509_get_dates( &p, end, &crt->valid_from, - &crt->valid_to ) ) != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( ret ); - } - - /* - * subject Name - */ - crt->subject_raw.p = p; - - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); - } - - if( len && ( ret = mbedtls_x509_get_name( &p, p + len, &crt->subject ) ) != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( ret ); - } - - crt->subject_raw.len = p - crt->subject_raw.p; - - /* - * SubjectPublicKeyInfo - */ - crt->pk_raw.p = p; - if( ( ret = mbedtls_pk_parse_subpubkey( &p, end, &crt->pk ) ) != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( ret ); - } - crt->pk_raw.len = p - crt->pk_raw.p; - - /* - * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, - * -- If present, version shall be v2 or v3 - * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, - * -- If present, version shall be v2 or v3 - * extensions [3] EXPLICIT Extensions OPTIONAL - * -- If present, version shall be v3 - */ - if( crt->version == 2 || crt->version == 3 ) - { - ret = x509_get_uid( &p, end, &crt->issuer_id, 1 ); - if( ret != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( ret ); - } - } - - if( crt->version == 2 || crt->version == 3 ) - { - ret = x509_get_uid( &p, end, &crt->subject_id, 2 ); - if( ret != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( ret ); - } - } - -#if !defined(MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3) - if( crt->version == 3 ) -#endif - { - ret = x509_get_crt_ext( &p, end, crt ); - if( ret != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( ret ); - } - } - - if( p != end ) - { - mbedtls_x509_crt_free( crt ); - return( MBEDTLS_ERR_X509_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - } - - end = crt_end; - - /* - * } - * -- end of TBSCertificate - * - * signatureAlgorithm AlgorithmIdentifier, - * signatureValue BIT STRING - */ - if( ( ret = mbedtls_x509_get_alg( &p, end, &sig_oid2, &sig_params2 ) ) != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( ret ); - } - - if( crt->sig_oid.len != sig_oid2.len || - memcmp( crt->sig_oid.p, sig_oid2.p, crt->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_crt_free( crt ); - return( MBEDTLS_ERR_X509_SIG_MISMATCH ); - } - - if( ( ret = mbedtls_x509_get_sig( &p, end, &crt->sig ) ) != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( ret ); - } - - if( p != end ) - { - mbedtls_x509_crt_free( crt ); - return( MBEDTLS_ERR_X509_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - } - - return( 0 ); -} - -/* - * Parse one X.509 certificate in DER format from a buffer and add them to a - * chained list - */ -static int mbedtls_x509_crt_parse_der_internal( mbedtls_x509_crt *chain, - const unsigned char *buf, - size_t buflen, - int make_copy ) -{ - int ret; - mbedtls_x509_crt *crt = chain, *prev = NULL; - - /* - * Check for valid input - */ - if( crt == NULL || buf == NULL ) - return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); - - while( crt->version != 0 && crt->next != NULL ) - { - prev = crt; - crt = crt->next; - } - - /* - * Add new certificate on the end of the chain if needed. - */ - if( crt->version != 0 && crt->next == NULL ) - { - crt->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) ); - - if( crt->next == NULL ) - return( MBEDTLS_ERR_X509_ALLOC_FAILED ); - - prev = crt; - mbedtls_x509_crt_init( crt->next ); - crt = crt->next; - } - - if( ( ret = x509_crt_parse_der_core( crt, buf, buflen, make_copy ) ) != 0 ) - { - if( prev ) - prev->next = NULL; - - if( crt != chain ) - mbedtls_free( crt ); - - return( ret ); - } - - return( 0 ); -} - -int mbedtls_x509_crt_parse_der_nocopy( mbedtls_x509_crt *chain, - const unsigned char *buf, - size_t buflen ) -{ - return( mbedtls_x509_crt_parse_der_internal( chain, buf, buflen, 0 ) ); -} - -int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, - const unsigned char *buf, - size_t buflen ) -{ - return( mbedtls_x509_crt_parse_der_internal( chain, buf, buflen, 1 ) ); -} - -/* - * Parse one or more PEM certificates from a buffer and add them to the chained - * list - */ -int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, - const unsigned char *buf, - size_t buflen ) -{ -#if defined(MBEDTLS_PEM_PARSE_C) - int success = 0, first_error = 0, total_failed = 0; - int buf_format = MBEDTLS_X509_FORMAT_DER; -#endif - - /* - * Check for valid input - */ - if( chain == NULL || buf == NULL ) - return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); - - /* - * Determine buffer content. Buffer contains either one DER certificate or - * one or more PEM certificates. - */ -#if defined(MBEDTLS_PEM_PARSE_C) - if( buflen != 0 && buf[buflen - 1] == '\0' && - strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL ) - { - buf_format = MBEDTLS_X509_FORMAT_PEM; - } - - if( buf_format == MBEDTLS_X509_FORMAT_DER ) - return mbedtls_x509_crt_parse_der( chain, buf, buflen ); -#else - return mbedtls_x509_crt_parse_der( chain, buf, buflen ); -#endif - -#if defined(MBEDTLS_PEM_PARSE_C) - if( buf_format == MBEDTLS_X509_FORMAT_PEM ) - { - int ret; - mbedtls_pem_context pem; - - /* 1 rather than 0 since the terminating NULL byte is counted in */ - while( buflen > 1 ) - { - size_t use_len; - mbedtls_pem_init( &pem ); - - /* If we get there, we know the string is null-terminated */ - ret = mbedtls_pem_read_buffer( &pem, - "-----BEGIN CERTIFICATE-----", - "-----END CERTIFICATE-----", - buf, NULL, 0, &use_len ); - - if( ret == 0 ) - { - /* - * Was PEM encoded - */ - buflen -= use_len; - buf += use_len; - } - else if( ret == MBEDTLS_ERR_PEM_BAD_INPUT_DATA ) - { - return( ret ); - } - else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) - { - mbedtls_pem_free( &pem ); - - /* - * PEM header and footer were found - */ - buflen -= use_len; - buf += use_len; - - if( first_error == 0 ) - first_error = ret; - - total_failed++; - continue; - } - else - break; - - ret = mbedtls_x509_crt_parse_der( chain, pem.buf, pem.buflen ); - - mbedtls_pem_free( &pem ); - - if( ret != 0 ) - { - /* - * Quit parsing on a memory error - */ - if( ret == MBEDTLS_ERR_X509_ALLOC_FAILED ) - return( ret ); - - if( first_error == 0 ) - first_error = ret; - - total_failed++; - continue; - } - - success = 1; - } - } - - if( success ) - return( total_failed ); - else if( first_error ) - return( first_error ); - else - return( MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT ); -#endif /* MBEDTLS_PEM_PARSE_C */ -} - -#if defined(MBEDTLS_FS_IO) -/* - * Load one or more certificates and add them to the chained list - */ -int mbedtls_x509_crt_parse_file( mbedtls_x509_crt *chain, const char *path ) -{ - int ret; - size_t n; - unsigned char *buf; - - if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 ) - return( ret ); - - ret = mbedtls_x509_crt_parse( chain, buf, n ); - - mbedtls_platform_zeroize( buf, n ); - mbedtls_free( buf ); - - return( ret ); -} - -int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ) -{ - int ret = 0; -#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) - int w_ret; - WCHAR szDir[MAX_PATH]; - char filename[MAX_PATH]; - char *p; - size_t len = strlen( path ); - - WIN32_FIND_DATAW file_data; - HANDLE hFind; - - if( len > MAX_PATH - 3 ) - return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); - - memset( szDir, 0, sizeof(szDir) ); - memset( filename, 0, MAX_PATH ); - memcpy( filename, path, len ); - filename[len++] = '\\'; - p = filename + len; - filename[len++] = '*'; - - w_ret = MultiByteToWideChar( CP_ACP, 0, filename, (int)len, szDir, - MAX_PATH - 3 ); - if( w_ret == 0 ) - return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); - - hFind = FindFirstFileW( szDir, &file_data ); - if( hFind == INVALID_HANDLE_VALUE ) - return( MBEDTLS_ERR_X509_FILE_IO_ERROR ); - - len = MAX_PATH - len; - do - { - memset( p, 0, len ); - - if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) - continue; - - w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName, - lstrlenW( file_data.cFileName ), - p, (int) len - 1, - NULL, NULL ); - if( w_ret == 0 ) - { - ret = MBEDTLS_ERR_X509_FILE_IO_ERROR; - goto cleanup; - } - - w_ret = mbedtls_x509_crt_parse_file( chain, filename ); - if( w_ret < 0 ) - ret++; - else - ret += w_ret; - } - while( FindNextFileW( hFind, &file_data ) != 0 ); - - if( GetLastError() != ERROR_NO_MORE_FILES ) - ret = MBEDTLS_ERR_X509_FILE_IO_ERROR; - -cleanup: - FindClose( hFind ); -#else /* _WIN32 */ - int t_ret; - int snp_ret; - struct stat sb; - struct dirent *entry; - char entry_name[MBEDTLS_X509_MAX_FILE_PATH_LEN]; - DIR *dir = opendir( path ); - - if( dir == NULL ) - return( MBEDTLS_ERR_X509_FILE_IO_ERROR ); - -#if defined(MBEDTLS_THREADING_C) - if( ( ret = mbedtls_mutex_lock( &mbedtls_threading_readdir_mutex ) ) != 0 ) - { - closedir( dir ); - return( ret ); - } -#endif /* MBEDTLS_THREADING_C */ - - while( ( entry = readdir( dir ) ) != NULL ) - { - snp_ret = mbedtls_snprintf( entry_name, sizeof entry_name, - "%s/%s", path, entry->d_name ); - - if( snp_ret < 0 || (size_t)snp_ret >= sizeof entry_name ) - { - ret = MBEDTLS_ERR_X509_BUFFER_TOO_SMALL; - goto cleanup; - } - else if( stat( entry_name, &sb ) == -1 ) - { - ret = MBEDTLS_ERR_X509_FILE_IO_ERROR; - goto cleanup; - } - - if( !S_ISREG( sb.st_mode ) ) - continue; - - // Ignore parse errors - // - t_ret = mbedtls_x509_crt_parse_file( chain, entry_name ); - if( t_ret < 0 ) - ret++; - else - ret += t_ret; - } - -cleanup: - closedir( dir ); - -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_unlock( &mbedtls_threading_readdir_mutex ) != 0 ) - ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR; -#endif /* MBEDTLS_THREADING_C */ - -#endif /* _WIN32 */ - - return( ret ); -} -#endif /* MBEDTLS_FS_IO */ - -static int x509_info_subject_alt_name( char **buf, size_t *size, - const mbedtls_x509_sequence *subject_alt_name ) -{ - size_t i; - size_t n = *size; - char *p = *buf; - const mbedtls_x509_sequence *cur = subject_alt_name; - const char *sep = ""; - size_t sep_len = 0; - - while( cur != NULL ) - { - if( cur->buf.len + sep_len >= n ) - { - *p = '\0'; - return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL ); - } - - n -= cur->buf.len + sep_len; - for( i = 0; i < sep_len; i++ ) - *p++ = sep[i]; - for( i = 0; i < cur->buf.len; i++ ) - *p++ = cur->buf.p[i]; - - sep = ", "; - sep_len = 2; - - cur = cur->next; - } - - *p = '\0'; - - *size = n; - *buf = p; - - return( 0 ); -} - -#define PRINT_ITEM(i) \ - { \ - ret = mbedtls_snprintf( p, n, "%s" i, sep ); \ - MBEDTLS_X509_SAFE_SNPRINTF; \ - sep = ", "; \ - } - -#define CERT_TYPE(type,name) \ - if( ns_cert_type & type ) \ - PRINT_ITEM( name ); - -static int x509_info_cert_type( char **buf, size_t *size, - unsigned char ns_cert_type ) -{ - int ret; - size_t n = *size; - char *p = *buf; - const char *sep = ""; - - CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT, "SSL Client" ); - CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER, "SSL Server" ); - CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_EMAIL, "Email" ); - CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING, "Object Signing" ); - CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_RESERVED, "Reserved" ); - CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_CA, "SSL CA" ); - CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA, "Email CA" ); - CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA, "Object Signing CA" ); - - *size = n; - *buf = p; - - return( 0 ); -} - -#define KEY_USAGE(code,name) \ - if( key_usage & code ) \ - PRINT_ITEM( name ); - -static int x509_info_key_usage( char **buf, size_t *size, - unsigned int key_usage ) -{ - int ret; - size_t n = *size; - char *p = *buf; - const char *sep = ""; - - KEY_USAGE( MBEDTLS_X509_KU_DIGITAL_SIGNATURE, "Digital Signature" ); - KEY_USAGE( MBEDTLS_X509_KU_NON_REPUDIATION, "Non Repudiation" ); - KEY_USAGE( MBEDTLS_X509_KU_KEY_ENCIPHERMENT, "Key Encipherment" ); - KEY_USAGE( MBEDTLS_X509_KU_DATA_ENCIPHERMENT, "Data Encipherment" ); - KEY_USAGE( MBEDTLS_X509_KU_KEY_AGREEMENT, "Key Agreement" ); - KEY_USAGE( MBEDTLS_X509_KU_KEY_CERT_SIGN, "Key Cert Sign" ); - KEY_USAGE( MBEDTLS_X509_KU_CRL_SIGN, "CRL Sign" ); - KEY_USAGE( MBEDTLS_X509_KU_ENCIPHER_ONLY, "Encipher Only" ); - KEY_USAGE( MBEDTLS_X509_KU_DECIPHER_ONLY, "Decipher Only" ); - - *size = n; - *buf = p; - - return( 0 ); -} - -static int x509_info_ext_key_usage( char **buf, size_t *size, - const mbedtls_x509_sequence *extended_key_usage ) -{ - int ret; - const char *desc; - size_t n = *size; - char *p = *buf; - const mbedtls_x509_sequence *cur = extended_key_usage; - const char *sep = ""; - - while( cur != NULL ) - { - if( mbedtls_oid_get_extended_key_usage( &cur->buf, &desc ) != 0 ) - desc = "???"; - - ret = mbedtls_snprintf( p, n, "%s%s", sep, desc ); - MBEDTLS_X509_SAFE_SNPRINTF; - - sep = ", "; - - cur = cur->next; - } - - *size = n; - *buf = p; - - return( 0 ); -} - -/* - * Return an informational string about the certificate. - */ -#define BEFORE_COLON 18 -#define BC "18" -int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix, - const mbedtls_x509_crt *crt ) -{ - int ret; - size_t n; - char *p; - char key_size_str[BEFORE_COLON]; - - p = buf; - n = size; - - if( NULL == crt ) - { - ret = mbedtls_snprintf( p, n, "\nCertificate is uninitialised!\n" ); - MBEDTLS_X509_SAFE_SNPRINTF; - - return( (int) ( size - n ) ); - } - - ret = mbedtls_snprintf( p, n, "%scert. version : %d\n", - prefix, crt->version ); - MBEDTLS_X509_SAFE_SNPRINTF; - ret = mbedtls_snprintf( p, n, "%sserial number : ", - prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_x509_serial_gets( p, n, &crt->serial ); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_snprintf( p, n, "\n%sissuer name : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; - ret = mbedtls_x509_dn_gets( p, n, &crt->issuer ); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_snprintf( p, n, "\n%ssubject name : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; - ret = mbedtls_x509_dn_gets( p, n, &crt->subject ); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_snprintf( p, n, "\n%sissued on : " \ - "%04d-%02d-%02d %02d:%02d:%02d", prefix, - crt->valid_from.year, crt->valid_from.mon, - crt->valid_from.day, crt->valid_from.hour, - crt->valid_from.min, crt->valid_from.sec ); - MBEDTLS_X509_SAFE_SNPRINTF; - - ret = mbedtls_snprintf( p, n, "\n%sexpires on : " \ - "%04d-%02d-%02d %02d:%02d:%02d", prefix, - crt->valid_to.year, crt->valid_to.mon, - crt->valid_to.day, crt->valid_to.hour, - crt->valid_to.min, crt->valid_to.sec ); - 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, &crt->sig_oid, crt->sig_pk, - crt->sig_md, crt->sig_opts ); - MBEDTLS_X509_SAFE_SNPRINTF; - - /* Key size */ - if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON, - mbedtls_pk_get_name( &crt->pk ) ) ) != 0 ) - { - return( ret ); - } - - ret = mbedtls_snprintf( p, n, "\n%s%-" BC "s: %d bits", prefix, key_size_str, - (int) mbedtls_pk_get_bitlen( &crt->pk ) ); - MBEDTLS_X509_SAFE_SNPRINTF; - - /* - * Optional extensions - */ - - if( crt->ext_types & MBEDTLS_X509_EXT_BASIC_CONSTRAINTS ) - { - ret = mbedtls_snprintf( p, n, "\n%sbasic constraints : CA=%s", prefix, - crt->ca_istrue ? "true" : "false" ); - MBEDTLS_X509_SAFE_SNPRINTF; - - if( crt->max_pathlen > 0 ) - { - ret = mbedtls_snprintf( p, n, ", max_pathlen=%d", crt->max_pathlen - 1 ); - MBEDTLS_X509_SAFE_SNPRINTF; - } - } - - if( crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME ) - { - ret = mbedtls_snprintf( p, n, "\n%ssubject alt name : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; - - if( ( ret = x509_info_subject_alt_name( &p, &n, - &crt->subject_alt_names ) ) != 0 ) - return( ret ); - } - - if( crt->ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE ) - { - ret = mbedtls_snprintf( p, n, "\n%scert. type : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; - - if( ( ret = x509_info_cert_type( &p, &n, crt->ns_cert_type ) ) != 0 ) - return( ret ); - } - - if( crt->ext_types & MBEDTLS_X509_EXT_KEY_USAGE ) - { - ret = mbedtls_snprintf( p, n, "\n%skey usage : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; - - if( ( ret = x509_info_key_usage( &p, &n, crt->key_usage ) ) != 0 ) - return( ret ); - } - - if( crt->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE ) - { - ret = mbedtls_snprintf( p, n, "\n%sext key usage : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; - - if( ( ret = x509_info_ext_key_usage( &p, &n, - &crt->ext_key_usage ) ) != 0 ) - return( ret ); - } - - ret = mbedtls_snprintf( p, n, "\n" ); - MBEDTLS_X509_SAFE_SNPRINTF; - - return( (int) ( size - n ) ); -} - -struct x509_crt_verify_string { - int code; - const char *string; -}; - -static const struct x509_crt_verify_string x509_crt_verify_strings[] = { - { MBEDTLS_X509_BADCERT_EXPIRED, "The certificate validity has expired" }, - { MBEDTLS_X509_BADCERT_REVOKED, "The certificate has been revoked (is on a CRL)" }, - { MBEDTLS_X509_BADCERT_CN_MISMATCH, "The certificate Common Name (CN) does not match with the expected CN" }, - { MBEDTLS_X509_BADCERT_NOT_TRUSTED, "The certificate is not correctly signed by the trusted CA" }, - { MBEDTLS_X509_BADCRL_NOT_TRUSTED, "The CRL is not correctly signed by the trusted CA" }, - { MBEDTLS_X509_BADCRL_EXPIRED, "The CRL is expired" }, - { MBEDTLS_X509_BADCERT_MISSING, "Certificate was missing" }, - { MBEDTLS_X509_BADCERT_SKIP_VERIFY, "Certificate verification was skipped" }, - { MBEDTLS_X509_BADCERT_OTHER, "Other reason (can be used by verify callback)" }, - { MBEDTLS_X509_BADCERT_FUTURE, "The certificate validity starts in the future" }, - { MBEDTLS_X509_BADCRL_FUTURE, "The CRL is from the future" }, - { MBEDTLS_X509_BADCERT_KEY_USAGE, "Usage does not match the keyUsage extension" }, - { MBEDTLS_X509_BADCERT_EXT_KEY_USAGE, "Usage does not match the extendedKeyUsage extension" }, - { MBEDTLS_X509_BADCERT_NS_CERT_TYPE, "Usage does not match the nsCertType extension" }, - { MBEDTLS_X509_BADCERT_BAD_MD, "The certificate is signed with an unacceptable hash." }, - { MBEDTLS_X509_BADCERT_BAD_PK, "The certificate is signed with an unacceptable PK alg (eg RSA vs ECDSA)." }, - { MBEDTLS_X509_BADCERT_BAD_KEY, "The certificate is signed with an unacceptable key (eg bad curve, RSA too short)." }, - { MBEDTLS_X509_BADCRL_BAD_MD, "The CRL is signed with an unacceptable hash." }, - { MBEDTLS_X509_BADCRL_BAD_PK, "The CRL is signed with an unacceptable PK alg (eg RSA vs ECDSA)." }, - { MBEDTLS_X509_BADCRL_BAD_KEY, "The CRL is signed with an unacceptable key (eg bad curve, RSA too short)." }, - { 0, NULL } -}; - -int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix, - uint32_t flags ) -{ - int ret; - const struct x509_crt_verify_string *cur; - char *p = buf; - size_t n = size; - - for( cur = x509_crt_verify_strings; cur->string != NULL ; cur++ ) - { - if( ( flags & cur->code ) == 0 ) - continue; - - ret = mbedtls_snprintf( p, n, "%s%s\n", prefix, cur->string ); - MBEDTLS_X509_SAFE_SNPRINTF; - flags ^= cur->code; - } - - if( flags != 0 ) - { - ret = mbedtls_snprintf( p, n, "%sUnknown reason " - "(this should not happen)\n", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; - } - - return( (int) ( size - n ) ); -} - -#if defined(MBEDTLS_X509_CHECK_KEY_USAGE) -int mbedtls_x509_crt_check_key_usage( const mbedtls_x509_crt *crt, - unsigned int usage ) -{ - unsigned int usage_must, usage_may; - unsigned int may_mask = MBEDTLS_X509_KU_ENCIPHER_ONLY - | MBEDTLS_X509_KU_DECIPHER_ONLY; - - if( ( crt->ext_types & MBEDTLS_X509_EXT_KEY_USAGE ) == 0 ) - return( 0 ); - - usage_must = usage & ~may_mask; - - if( ( ( crt->key_usage & ~may_mask ) & usage_must ) != usage_must ) - return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); - - usage_may = usage & may_mask; - - if( ( ( crt->key_usage & may_mask ) | usage_may ) != usage_may ) - return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); - - return( 0 ); -} -#endif - -#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE) -int mbedtls_x509_crt_check_extended_key_usage( const mbedtls_x509_crt *crt, - const char *usage_oid, - size_t usage_len ) -{ - const mbedtls_x509_sequence *cur; - - /* Extension is not mandatory, absent means no restriction */ - if( ( crt->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE ) == 0 ) - return( 0 ); - - /* - * Look for the requested usage (or wildcard ANY) in our list - */ - for( cur = &crt->ext_key_usage; cur != NULL; cur = cur->next ) - { - const mbedtls_x509_buf *cur_oid = &cur->buf; - - if( cur_oid->len == usage_len && - memcmp( cur_oid->p, usage_oid, usage_len ) == 0 ) - { - return( 0 ); - } - - if( MBEDTLS_OID_CMP( MBEDTLS_OID_ANY_EXTENDED_KEY_USAGE, cur_oid ) == 0 ) - return( 0 ); - } - - return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); -} -#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */ - -#if defined(MBEDTLS_X509_CRL_PARSE_C) -/* - * Return 1 if the certificate is revoked, or 0 otherwise. - */ -int mbedtls_x509_crt_is_revoked( const mbedtls_x509_crt *crt, const mbedtls_x509_crl *crl ) -{ - const mbedtls_x509_crl_entry *cur = &crl->entry; - - while( cur != NULL && cur->serial.len != 0 ) - { - if( crt->serial.len == cur->serial.len && - memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 ) - { - if( mbedtls_x509_time_is_past( &cur->revocation_date ) ) - return( 1 ); - } - - cur = cur->next; - } - - return( 0 ); -} - -/* - * Check that the given certificate is not revoked according to the CRL. - * Skip validation if no CRL for the given CA is present. - */ -static int x509_crt_verifycrl( mbedtls_x509_crt *crt, mbedtls_x509_crt *ca, - mbedtls_x509_crl *crl_list, - const mbedtls_x509_crt_profile *profile ) -{ - int flags = 0; - unsigned char hash[MBEDTLS_MD_MAX_SIZE]; - const mbedtls_md_info_t *md_info; - - if( ca == NULL ) - return( flags ); - - while( crl_list != NULL ) - { - if( crl_list->version == 0 || - x509_name_cmp( &crl_list->issuer, &ca->subject ) != 0 ) - { - crl_list = crl_list->next; - continue; - } - - /* - * Check if the CA is configured to sign CRLs - */ -#if defined(MBEDTLS_X509_CHECK_KEY_USAGE) - if( mbedtls_x509_crt_check_key_usage( ca, - MBEDTLS_X509_KU_CRL_SIGN ) != 0 ) - { - flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED; - break; - } -#endif - - /* - * Check if CRL is correctly signed by the trusted CA - */ - if( x509_profile_check_md_alg( profile, crl_list->sig_md ) != 0 ) - flags |= MBEDTLS_X509_BADCRL_BAD_MD; - - if( x509_profile_check_pk_alg( profile, crl_list->sig_pk ) != 0 ) - flags |= MBEDTLS_X509_BADCRL_BAD_PK; - - md_info = mbedtls_md_info_from_type( crl_list->sig_md ); - if( mbedtls_md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash ) != 0 ) - { - /* Note: this can't happen except after an internal error */ - flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED; - break; - } - - if( x509_profile_check_key( profile, &ca->pk ) != 0 ) - flags |= MBEDTLS_X509_BADCERT_BAD_KEY; - - if( mbedtls_pk_verify_ext( crl_list->sig_pk, crl_list->sig_opts, &ca->pk, - crl_list->sig_md, hash, mbedtls_md_get_size( md_info ), - crl_list->sig.p, crl_list->sig.len ) != 0 ) - { - flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED; - break; - } - - /* - * Check for validity of CRL (Do not drop out) - */ - if( mbedtls_x509_time_is_past( &crl_list->next_update ) ) - flags |= MBEDTLS_X509_BADCRL_EXPIRED; - - if( mbedtls_x509_time_is_future( &crl_list->this_update ) ) - flags |= MBEDTLS_X509_BADCRL_FUTURE; - - /* - * Check if certificate is revoked - */ - if( mbedtls_x509_crt_is_revoked( crt, crl_list ) ) - { - flags |= MBEDTLS_X509_BADCERT_REVOKED; - break; - } - - crl_list = crl_list->next; - } - - return( flags ); -} -#endif /* MBEDTLS_X509_CRL_PARSE_C */ - -/* - * Check the signature of a certificate by its parent - */ -static int x509_crt_check_signature( const mbedtls_x509_crt *child, - mbedtls_x509_crt *parent, - mbedtls_x509_crt_restart_ctx *rs_ctx ) -{ - unsigned char hash[MBEDTLS_MD_MAX_SIZE]; - size_t hash_len; -#if !defined(MBEDTLS_USE_PSA_CRYPTO) - const mbedtls_md_info_t *md_info; - md_info = mbedtls_md_info_from_type( child->sig_md ); - hash_len = mbedtls_md_get_size( md_info ); - - /* Note: hash errors can happen only after an internal error */ - if( mbedtls_md( md_info, child->tbs.p, child->tbs.len, hash ) != 0 ) - return( -1 ); -#else - psa_hash_operation_t hash_operation = PSA_HASH_OPERATION_INIT; - psa_algorithm_t hash_alg = mbedtls_psa_translate_md( child->sig_md ); - - if( psa_hash_setup( &hash_operation, hash_alg ) != PSA_SUCCESS ) - return( -1 ); - - if( psa_hash_update( &hash_operation, child->tbs.p, child->tbs.len ) - != PSA_SUCCESS ) - { - return( -1 ); - } - - if( psa_hash_finish( &hash_operation, hash, sizeof( hash ), &hash_len ) - != PSA_SUCCESS ) - { - return( -1 ); - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - /* Skip expensive computation on obvious mismatch */ - if( ! mbedtls_pk_can_do( &parent->pk, child->sig_pk ) ) - return( -1 ); - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && child->sig_pk == MBEDTLS_PK_ECDSA ) - { - return( mbedtls_pk_verify_restartable( &parent->pk, - child->sig_md, hash, hash_len, - child->sig.p, child->sig.len, &rs_ctx->pk ) ); - } -#else - (void) rs_ctx; -#endif - - return( mbedtls_pk_verify_ext( child->sig_pk, child->sig_opts, &parent->pk, - child->sig_md, hash, hash_len, - child->sig.p, child->sig.len ) ); -} - -/* - * Check if 'parent' is a suitable parent (signing CA) for 'child'. - * Return 0 if yes, -1 if not. - * - * top means parent is a locally-trusted certificate - */ -static int x509_crt_check_parent( const mbedtls_x509_crt *child, - const mbedtls_x509_crt *parent, - int top ) -{ - int need_ca_bit; - - /* Parent must be the issuer */ - if( x509_name_cmp( &child->issuer, &parent->subject ) != 0 ) - return( -1 ); - - /* Parent must have the basicConstraints CA bit set as a general rule */ - need_ca_bit = 1; - - /* Exception: v1/v2 certificates that are locally trusted. */ - if( top && parent->version < 3 ) - need_ca_bit = 0; - - if( need_ca_bit && ! parent->ca_istrue ) - return( -1 ); - -#if defined(MBEDTLS_X509_CHECK_KEY_USAGE) - if( need_ca_bit && - mbedtls_x509_crt_check_key_usage( parent, MBEDTLS_X509_KU_KEY_CERT_SIGN ) != 0 ) - { - return( -1 ); - } -#endif - - return( 0 ); -} - -/* - * Find a suitable parent for child in candidates, or return NULL. - * - * Here suitable is defined as: - * 1. subject name matches child's issuer - * 2. if necessary, the CA bit is set and key usage allows signing certs - * 3. for trusted roots, the signature is correct - * (for intermediates, the signature is checked and the result reported) - * 4. pathlen constraints are satisfied - * - * If there's a suitable candidate which is also time-valid, return the first - * such. Otherwise, return the first suitable candidate (or NULL if there is - * none). - * - * The rationale for this rule is that someone could have a list of trusted - * roots with two versions on the same root with different validity periods. - * (At least one user reported having such a list and wanted it to just work.) - * The reason we don't just require time-validity is that generally there is - * only one version, and if it's expired we want the flags to state that - * rather than NOT_TRUSTED, as would be the case if we required it here. - * - * The rationale for rule 3 (signature for trusted roots) is that users might - * have two versions of the same CA with different keys in their list, and the - * way we select the correct one is by checking the signature (as we don't - * rely on key identifier extensions). (This is one way users might choose to - * handle key rollover, another relies on self-issued certs, see [SIRO].) - * - * Arguments: - * - [in] child: certificate for which we're looking for a parent - * - [in] candidates: chained list of potential parents - * - [out] r_parent: parent found (or NULL) - * - [out] r_signature_is_good: 1 if child signature by parent is valid, or 0 - * - [in] top: 1 if candidates consists of trusted roots, ie we're at the top - * of the chain, 0 otherwise - * - [in] path_cnt: number of intermediates seen so far - * - [in] self_cnt: number of self-signed intermediates seen so far - * (will never be greater than path_cnt) - * - [in-out] rs_ctx: context for restarting operations - * - * Return value: - * - 0 on success - * - MBEDTLS_ERR_ECP_IN_PROGRESS otherwise - */ -static int x509_crt_find_parent_in( - mbedtls_x509_crt *child, - mbedtls_x509_crt *candidates, - mbedtls_x509_crt **r_parent, - int *r_signature_is_good, - int top, - unsigned path_cnt, - unsigned self_cnt, - mbedtls_x509_crt_restart_ctx *rs_ctx ) -{ - int ret; - mbedtls_x509_crt *parent, *fallback_parent; - int signature_is_good, fallback_signature_is_good; - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - /* did we have something in progress? */ - if( rs_ctx != NULL && rs_ctx->parent != NULL ) - { - /* restore saved state */ - parent = rs_ctx->parent; - fallback_parent = rs_ctx->fallback_parent; - fallback_signature_is_good = rs_ctx->fallback_signature_is_good; - - /* clear saved state */ - rs_ctx->parent = NULL; - rs_ctx->fallback_parent = NULL; - rs_ctx->fallback_signature_is_good = 0; - - /* resume where we left */ - goto check_signature; - } -#endif - - fallback_parent = NULL; - fallback_signature_is_good = 0; - - for( parent = candidates; parent != NULL; parent = parent->next ) - { - /* basic parenting skills (name, CA bit, key usage) */ - if( x509_crt_check_parent( child, parent, top ) != 0 ) - continue; - - /* +1 because stored max_pathlen is 1 higher that the actual value */ - if( parent->max_pathlen > 0 && - (size_t) parent->max_pathlen < 1 + path_cnt - self_cnt ) - { - continue; - } - - /* Signature */ -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) -check_signature: -#endif - ret = x509_crt_check_signature( child, parent, rs_ctx ); - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) - { - /* save state */ - rs_ctx->parent = parent; - rs_ctx->fallback_parent = fallback_parent; - rs_ctx->fallback_signature_is_good = fallback_signature_is_good; - - return( ret ); - } -#else - (void) ret; -#endif - - signature_is_good = ret == 0; - if( top && ! signature_is_good ) - continue; - - /* optional time check */ - if( mbedtls_x509_time_is_past( &parent->valid_to ) || - mbedtls_x509_time_is_future( &parent->valid_from ) ) - { - if( fallback_parent == NULL ) - { - fallback_parent = parent; - fallback_signature_is_good = signature_is_good; - } - - continue; - } - - break; - } - - if( parent != NULL ) - { - *r_parent = parent; - *r_signature_is_good = signature_is_good; - } - else - { - *r_parent = fallback_parent; - *r_signature_is_good = fallback_signature_is_good; - } - - return( 0 ); -} - -/* - * Find a parent in trusted CAs or the provided chain, or return NULL. - * - * Searches in trusted CAs first, and return the first suitable parent found - * (see find_parent_in() for definition of suitable). - * - * Arguments: - * - [in] child: certificate for which we're looking for a parent, followed - * by a chain of possible intermediates - * - [in] trust_ca: list of locally trusted certificates - * - [out] parent: parent found (or NULL) - * - [out] parent_is_trusted: 1 if returned `parent` is trusted, or 0 - * - [out] signature_is_good: 1 if child signature by parent is valid, or 0 - * - [in] path_cnt: number of links in the chain so far (EE -> ... -> child) - * - [in] self_cnt: number of self-signed certs in the chain so far - * (will always be no greater than path_cnt) - * - [in-out] rs_ctx: context for restarting operations - * - * Return value: - * - 0 on success - * - MBEDTLS_ERR_ECP_IN_PROGRESS otherwise - */ -static int x509_crt_find_parent( - mbedtls_x509_crt *child, - mbedtls_x509_crt *trust_ca, - mbedtls_x509_crt **parent, - int *parent_is_trusted, - int *signature_is_good, - unsigned path_cnt, - unsigned self_cnt, - mbedtls_x509_crt_restart_ctx *rs_ctx ) -{ - int ret; - mbedtls_x509_crt *search_list; - - *parent_is_trusted = 1; - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - /* restore then clear saved state if we have some stored */ - if( rs_ctx != NULL && rs_ctx->parent_is_trusted != -1 ) - { - *parent_is_trusted = rs_ctx->parent_is_trusted; - rs_ctx->parent_is_trusted = -1; - } -#endif - - while( 1 ) { - search_list = *parent_is_trusted ? trust_ca : child->next; - - ret = x509_crt_find_parent_in( child, search_list, - parent, signature_is_good, - *parent_is_trusted, - path_cnt, self_cnt, rs_ctx ); - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) - { - /* save state */ - rs_ctx->parent_is_trusted = *parent_is_trusted; - return( ret ); - } -#else - (void) ret; -#endif - - /* stop here if found or already in second iteration */ - if( *parent != NULL || *parent_is_trusted == 0 ) - break; - - /* prepare second iteration */ - *parent_is_trusted = 0; - } - - /* extra precaution against mistakes in the caller */ - if( *parent == NULL ) - { - *parent_is_trusted = 0; - *signature_is_good = 0; - } - - return( 0 ); -} - -/* - * Check if an end-entity certificate is locally trusted - * - * Currently we require such certificates to be self-signed (actually only - * check for self-issued as self-signatures are not checked) - */ -static int x509_crt_check_ee_locally_trusted( - mbedtls_x509_crt *crt, - mbedtls_x509_crt *trust_ca ) -{ - mbedtls_x509_crt *cur; - - /* must be self-issued */ - if( x509_name_cmp( &crt->issuer, &crt->subject ) != 0 ) - return( -1 ); - - /* look for an exact match with trusted cert */ - for( cur = trust_ca; cur != NULL; cur = cur->next ) - { - if( crt->raw.len == cur->raw.len && - memcmp( crt->raw.p, cur->raw.p, crt->raw.len ) == 0 ) - { - return( 0 ); - } - } - - /* too bad */ - return( -1 ); -} - -/* - * Build and verify a certificate chain - * - * Given a peer-provided list of certificates EE, C1, ..., Cn and - * a list of trusted certs R1, ... Rp, try to build and verify a chain - * EE, Ci1, ... Ciq [, Rj] - * such that every cert in the chain is a child of the next one, - * jumping to a trusted root as early as possible. - * - * Verify that chain and return it with flags for all issues found. - * - * Special cases: - * - EE == Rj -> return a one-element list containing it - * - EE, Ci1, ..., Ciq cannot be continued with a trusted root - * -> return that chain with NOT_TRUSTED set on Ciq - * - * Tests for (aspects of) this function should include at least: - * - trusted EE - * - EE -> trusted root - * - EE -> intermediate CA -> trusted root - * - if relevant: EE untrusted - * - if relevant: EE -> intermediate, untrusted - * with the aspect under test checked at each relevant level (EE, int, root). - * For some aspects longer chains are required, but usually length 2 is - * enough (but length 1 is not in general). - * - * Arguments: - * - [in] crt: the cert list EE, C1, ..., Cn - * - [in] trust_ca: the trusted list R1, ..., Rp - * - [in] ca_crl, profile: as in verify_with_profile() - * - [out] ver_chain: the built and verified chain - * Only valid when return value is 0, may contain garbage otherwise! - * Restart note: need not be the same when calling again to resume. - * - [in-out] rs_ctx: context for restarting operations - * - * Return value: - * - non-zero if the chain could not be fully built and examined - * - 0 is the chain was successfully built and examined, - * even if it was found to be invalid - */ -static int x509_crt_verify_chain( - mbedtls_x509_crt *crt, - mbedtls_x509_crt *trust_ca, - mbedtls_x509_crl *ca_crl, - mbedtls_x509_crt_ca_cb_t f_ca_cb, - void *p_ca_cb, - const mbedtls_x509_crt_profile *profile, - mbedtls_x509_crt_verify_chain *ver_chain, - mbedtls_x509_crt_restart_ctx *rs_ctx ) -{ - /* Don't initialize any of those variables here, so that the compiler can - * catch potential issues with jumping ahead when restarting */ - int ret; - uint32_t *flags; - mbedtls_x509_crt_verify_chain_item *cur; - mbedtls_x509_crt *child; - mbedtls_x509_crt *parent; - int parent_is_trusted; - int child_is_trusted; - int signature_is_good; - unsigned self_cnt; - mbedtls_x509_crt *cur_trust_ca = NULL; - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - /* resume if we had an operation in progress */ - if( rs_ctx != NULL && rs_ctx->in_progress == x509_crt_rs_find_parent ) - { - /* restore saved state */ - *ver_chain = rs_ctx->ver_chain; /* struct copy */ - self_cnt = rs_ctx->self_cnt; - - /* restore derived state */ - cur = &ver_chain->items[ver_chain->len - 1]; - child = cur->crt; - flags = &cur->flags; - - goto find_parent; - } -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - - child = crt; - self_cnt = 0; - parent_is_trusted = 0; - child_is_trusted = 0; - - while( 1 ) { - /* Add certificate to the verification chain */ - cur = &ver_chain->items[ver_chain->len]; - cur->crt = child; - cur->flags = 0; - ver_chain->len++; - flags = &cur->flags; - - /* Check time-validity (all certificates) */ - if( mbedtls_x509_time_is_past( &child->valid_to ) ) - *flags |= MBEDTLS_X509_BADCERT_EXPIRED; - - if( mbedtls_x509_time_is_future( &child->valid_from ) ) - *flags |= MBEDTLS_X509_BADCERT_FUTURE; - - /* Stop here for trusted roots (but not for trusted EE certs) */ - if( child_is_trusted ) - return( 0 ); - - /* Check signature algorithm: MD & PK algs */ - if( x509_profile_check_md_alg( profile, child->sig_md ) != 0 ) - *flags |= MBEDTLS_X509_BADCERT_BAD_MD; - - if( x509_profile_check_pk_alg( profile, child->sig_pk ) != 0 ) - *flags |= MBEDTLS_X509_BADCERT_BAD_PK; - - /* Special case: EE certs that are locally trusted */ - if( ver_chain->len == 1 && - x509_crt_check_ee_locally_trusted( child, trust_ca ) == 0 ) - { - return( 0 ); - } - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) -find_parent: -#endif - - /* Obtain list of potential trusted signers from CA callback, - * or use statically provided list. */ -#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) - if( f_ca_cb != NULL ) - { - mbedtls_x509_crt_free( ver_chain->trust_ca_cb_result ); - mbedtls_free( ver_chain->trust_ca_cb_result ); - ver_chain->trust_ca_cb_result = NULL; - - ret = f_ca_cb( p_ca_cb, child, &ver_chain->trust_ca_cb_result ); - if( ret != 0 ) - return( MBEDTLS_ERR_X509_FATAL_ERROR ); - - cur_trust_ca = ver_chain->trust_ca_cb_result; - } - else -#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */ - { - ((void) f_ca_cb); - ((void) p_ca_cb); - cur_trust_ca = trust_ca; - } - - /* Look for a parent in trusted CAs or up the chain */ - ret = x509_crt_find_parent( child, cur_trust_ca, &parent, - &parent_is_trusted, &signature_is_good, - ver_chain->len - 1, self_cnt, rs_ctx ); - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) - { - /* save state */ - rs_ctx->in_progress = x509_crt_rs_find_parent; - rs_ctx->self_cnt = self_cnt; - rs_ctx->ver_chain = *ver_chain; /* struct copy */ - - return( ret ); - } -#else - (void) ret; -#endif - - /* No parent? We're done here */ - if( parent == NULL ) - { - *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED; - return( 0 ); - } - - /* Count intermediate self-issued (not necessarily self-signed) certs. - * These can occur with some strategies for key rollover, see [SIRO], - * and should be excluded from max_pathlen checks. */ - if( ver_chain->len != 1 && - x509_name_cmp( &child->issuer, &child->subject ) == 0 ) - { - self_cnt++; - } - - /* path_cnt is 0 for the first intermediate CA, - * and if parent is trusted it's not an intermediate CA */ - if( ! parent_is_trusted && - ver_chain->len > MBEDTLS_X509_MAX_INTERMEDIATE_CA ) - { - /* return immediately to avoid overflow the chain array */ - return( MBEDTLS_ERR_X509_FATAL_ERROR ); - } - - /* signature was checked while searching parent */ - if( ! signature_is_good ) - *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED; - - /* check size of signing key */ - if( x509_profile_check_key( profile, &parent->pk ) != 0 ) - *flags |= MBEDTLS_X509_BADCERT_BAD_KEY; - -#if defined(MBEDTLS_X509_CRL_PARSE_C) - /* Check trusted CA's CRL for the given crt */ - *flags |= x509_crt_verifycrl( child, parent, ca_crl, profile ); -#else - (void) ca_crl; -#endif - - /* prepare for next iteration */ - child = parent; - parent = NULL; - child_is_trusted = parent_is_trusted; - signature_is_good = 0; - } -} - -/* - * Check for CN match - */ -static int x509_crt_check_cn( const mbedtls_x509_buf *name, - const char *cn, size_t cn_len ) -{ - /* try exact match */ - if( name->len == cn_len && - x509_memcasecmp( cn, name->p, cn_len ) == 0 ) - { - return( 0 ); - } - - /* try wildcard match */ - if( x509_check_wildcard( cn, name ) == 0 ) - { - return( 0 ); - } - - return( -1 ); -} - -/* - * Verify the requested CN - only call this if cn is not NULL! - */ -static void x509_crt_verify_name( const mbedtls_x509_crt *crt, - const char *cn, - uint32_t *flags ) -{ - const mbedtls_x509_name *name; - const mbedtls_x509_sequence *cur; - size_t cn_len = strlen( cn ); - - if( crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME ) - { - for( cur = &crt->subject_alt_names; cur != NULL; cur = cur->next ) - { - if( x509_crt_check_cn( &cur->buf, cn, cn_len ) == 0 ) - break; - } - - if( cur == NULL ) - *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; - } - else - { - for( name = &crt->subject; name != NULL; name = name->next ) - { - if( MBEDTLS_OID_CMP( MBEDTLS_OID_AT_CN, &name->oid ) == 0 && - x509_crt_check_cn( &name->val, cn, cn_len ) == 0 ) - { - break; - } - } - - if( name == NULL ) - *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; - } -} - -/* - * Merge the flags for all certs in the chain, after calling callback - */ -static int x509_crt_merge_flags_with_cb( - uint32_t *flags, - const mbedtls_x509_crt_verify_chain *ver_chain, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy ) -{ - int ret; - unsigned i; - uint32_t cur_flags; - const mbedtls_x509_crt_verify_chain_item *cur; - - for( i = ver_chain->len; i != 0; --i ) - { - cur = &ver_chain->items[i-1]; - cur_flags = cur->flags; - - if( NULL != f_vrfy ) - if( ( ret = f_vrfy( p_vrfy, cur->crt, (int) i-1, &cur_flags ) ) != 0 ) - return( ret ); - - *flags |= cur_flags; - } - - return( 0 ); -} - -/* - * Verify the certificate validity, with profile, restartable version - * - * This function: - * - checks the requested CN (if any) - * - checks the type and size of the EE cert's key, - * as that isn't done as part of chain building/verification currently - * - builds and verifies the chain - * - then calls the callback and merges the flags - * - * The parameters pairs `trust_ca`, `ca_crl` and `f_ca_cb`, `p_ca_cb` - * are mutually exclusive: If `f_ca_cb != NULL`, it will be used by the - * verification routine to search for trusted signers, and CRLs will - * be disabled. Otherwise, `trust_ca` will be used as the static list - * of trusted signers, and `ca_crl` will be use as the static list - * of CRLs. - */ -static int x509_crt_verify_restartable_ca_cb( mbedtls_x509_crt *crt, - mbedtls_x509_crt *trust_ca, - mbedtls_x509_crl *ca_crl, - mbedtls_x509_crt_ca_cb_t f_ca_cb, - void *p_ca_cb, - const mbedtls_x509_crt_profile *profile, - const char *cn, uint32_t *flags, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy, - mbedtls_x509_crt_restart_ctx *rs_ctx ) -{ - int ret; - mbedtls_pk_type_t pk_type; - mbedtls_x509_crt_verify_chain ver_chain; - uint32_t ee_flags; - - *flags = 0; - ee_flags = 0; - x509_crt_verify_chain_reset( &ver_chain ); - - if( profile == NULL ) - { - ret = MBEDTLS_ERR_X509_BAD_INPUT_DATA; - goto exit; - } - - /* check name if requested */ - if( cn != NULL ) - x509_crt_verify_name( crt, cn, &ee_flags ); - - /* Check the type and size of the key */ - pk_type = mbedtls_pk_get_type( &crt->pk ); - - if( x509_profile_check_pk_alg( profile, pk_type ) != 0 ) - ee_flags |= MBEDTLS_X509_BADCERT_BAD_PK; - - if( x509_profile_check_key( profile, &crt->pk ) != 0 ) - ee_flags |= MBEDTLS_X509_BADCERT_BAD_KEY; - - /* Check the chain */ - ret = x509_crt_verify_chain( crt, trust_ca, ca_crl, - f_ca_cb, p_ca_cb, profile, - &ver_chain, rs_ctx ); - - if( ret != 0 ) - goto exit; - - /* Merge end-entity flags */ - ver_chain.items[0].flags |= ee_flags; - - /* Build final flags, calling callback on the way if any */ - ret = x509_crt_merge_flags_with_cb( flags, &ver_chain, f_vrfy, p_vrfy ); - -exit: - -#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) - mbedtls_x509_crt_free( ver_chain.trust_ca_cb_result ); - mbedtls_free( ver_chain.trust_ca_cb_result ); - ver_chain.trust_ca_cb_result = NULL; -#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */ - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && ret != MBEDTLS_ERR_ECP_IN_PROGRESS ) - mbedtls_x509_crt_restart_free( rs_ctx ); -#endif - - /* prevent misuse of the vrfy callback - VERIFY_FAILED would be ignored by - * the SSL module for authmode optional, but non-zero return from the - * callback means a fatal error so it shouldn't be ignored */ - if( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ) - ret = MBEDTLS_ERR_X509_FATAL_ERROR; - - if( ret != 0 ) - { - *flags = (uint32_t) -1; - return( ret ); - } - - if( *flags != 0 ) - return( MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ); - - return( 0 ); -} - - -/* - * Verify the certificate validity (default profile, not restartable) - */ -int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt, - mbedtls_x509_crt *trust_ca, - mbedtls_x509_crl *ca_crl, - const char *cn, uint32_t *flags, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy ) -{ - return( x509_crt_verify_restartable_ca_cb( crt, trust_ca, ca_crl, - NULL, NULL, - &mbedtls_x509_crt_profile_default, - cn, flags, - f_vrfy, p_vrfy, NULL ) ); -} - -/* - * Verify the certificate validity (user-chosen profile, not restartable) - */ -int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt, - mbedtls_x509_crt *trust_ca, - mbedtls_x509_crl *ca_crl, - const mbedtls_x509_crt_profile *profile, - const char *cn, uint32_t *flags, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy ) -{ - return( x509_crt_verify_restartable_ca_cb( crt, trust_ca, ca_crl, - NULL, NULL, - profile, cn, flags, - f_vrfy, p_vrfy, NULL ) ); -} - -#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) -/* - * Verify the certificate validity (user-chosen profile, CA callback, - * not restartable). - */ -int mbedtls_x509_crt_verify_with_ca_cb( mbedtls_x509_crt *crt, - mbedtls_x509_crt_ca_cb_t f_ca_cb, - void *p_ca_cb, - const mbedtls_x509_crt_profile *profile, - const char *cn, uint32_t *flags, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy ) -{ - return( x509_crt_verify_restartable_ca_cb( crt, NULL, NULL, - f_ca_cb, p_ca_cb, - profile, cn, flags, - f_vrfy, p_vrfy, NULL ) ); -} -#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */ - -int mbedtls_x509_crt_verify_restartable( mbedtls_x509_crt *crt, - mbedtls_x509_crt *trust_ca, - mbedtls_x509_crl *ca_crl, - const mbedtls_x509_crt_profile *profile, - const char *cn, uint32_t *flags, - int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), - void *p_vrfy, - mbedtls_x509_crt_restart_ctx *rs_ctx ) -{ - return( x509_crt_verify_restartable_ca_cb( crt, trust_ca, ca_crl, - NULL, NULL, - profile, cn, flags, - f_vrfy, p_vrfy, rs_ctx ) ); -} - - -/* - * Initialize a certificate chain - */ -void mbedtls_x509_crt_init( mbedtls_x509_crt *crt ) -{ - memset( crt, 0, sizeof(mbedtls_x509_crt) ); -} - -/* - * Unallocate all certificate data - */ -void mbedtls_x509_crt_free( mbedtls_x509_crt *crt ) -{ - mbedtls_x509_crt *cert_cur = crt; - mbedtls_x509_crt *cert_prv; - mbedtls_x509_name *name_cur; - mbedtls_x509_name *name_prv; - mbedtls_x509_sequence *seq_cur; - mbedtls_x509_sequence *seq_prv; - - if( crt == NULL ) - return; - - do - { - mbedtls_pk_free( &cert_cur->pk ); - -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) - mbedtls_free( cert_cur->sig_opts ); -#endif - - name_cur = cert_cur->issuer.next; - while( name_cur != NULL ) - { - name_prv = name_cur; - name_cur = name_cur->next; - mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) ); - mbedtls_free( name_prv ); - } - - name_cur = cert_cur->subject.next; - while( name_cur != NULL ) - { - name_prv = name_cur; - name_cur = name_cur->next; - mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) ); - mbedtls_free( name_prv ); - } - - seq_cur = cert_cur->ext_key_usage.next; - while( seq_cur != NULL ) - { - seq_prv = seq_cur; - seq_cur = seq_cur->next; - mbedtls_platform_zeroize( seq_prv, - sizeof( mbedtls_x509_sequence ) ); - mbedtls_free( seq_prv ); - } - - seq_cur = cert_cur->subject_alt_names.next; - while( seq_cur != NULL ) - { - seq_prv = seq_cur; - seq_cur = seq_cur->next; - mbedtls_platform_zeroize( seq_prv, - sizeof( mbedtls_x509_sequence ) ); - mbedtls_free( seq_prv ); - } - - if( cert_cur->raw.p != NULL && cert_cur->own_buffer ) - { - mbedtls_platform_zeroize( cert_cur->raw.p, cert_cur->raw.len ); - mbedtls_free( cert_cur->raw.p ); - } - - cert_cur = cert_cur->next; - } - while( cert_cur != NULL ); - - cert_cur = crt; - do - { - cert_prv = cert_cur; - cert_cur = cert_cur->next; - - mbedtls_platform_zeroize( cert_prv, sizeof( mbedtls_x509_crt ) ); - if( cert_prv != crt ) - mbedtls_free( cert_prv ); - } - while( cert_cur != NULL ); -} - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) -/* - * Initialize a restart context - */ -void mbedtls_x509_crt_restart_init( mbedtls_x509_crt_restart_ctx *ctx ) -{ - mbedtls_pk_restart_init( &ctx->pk ); - - ctx->parent = NULL; - ctx->fallback_parent = NULL; - ctx->fallback_signature_is_good = 0; - - ctx->parent_is_trusted = -1; - - ctx->in_progress = x509_crt_rs_none; - ctx->self_cnt = 0; - x509_crt_verify_chain_reset( &ctx->ver_chain ); -} - -/* - * Free the components of a restart context - */ -void mbedtls_x509_crt_restart_free( mbedtls_x509_crt_restart_ctx *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_pk_restart_free( &ctx->pk ); - mbedtls_x509_crt_restart_init( ctx ); -} -#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - -#endif /* MBEDTLS_X509_CRT_PARSE_C */ diff --git a/library/x509_csr.c b/library/x509_csr.c deleted file mode 100644 index c8c08c87b..000000000 --- a/library/x509_csr.c +++ /dev/null @@ -1,419 +0,0 @@ -/* - * X.509 Certificate Signing Request (CSR) parsing - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -/* - * 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 - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_X509_CSR_PARSE_C) - -#include "mbedtls/x509_csr.h" -#include "mbedtls/oid.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_PEM_PARSE_C) -#include "mbedtls/pem.h" -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#include -#define mbedtls_free free -#define mbedtls_calloc calloc -#define mbedtls_snprintf snprintf -#endif - -#if defined(MBEDTLS_FS_IO) || defined(EFIX64) || defined(EFI32) -#include -#endif - -/* - * Version ::= INTEGER { v1(0) } - */ -static int x509_csr_get_version( unsigned char **p, - const unsigned char *end, - int *ver ) -{ - int ret; - - if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 ) - { - if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) - { - *ver = 0; - return( 0 ); - } - - return( MBEDTLS_ERR_X509_INVALID_VERSION + ret ); - } - - 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 ) -{ - int ret; - 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_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_ERR_X509_INVALID_FORMAT + ret ); - } - - end = p + len; - csr->cri.len = 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_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 = 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_ERR_X509_INVALID_FORMAT + 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, - &csr->sig_opts ) ) != 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_ERR_X509_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - } - - return( 0 ); -} - -/* - * 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; - 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; - 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_platform_zeroize( buf, n ); - mbedtls_free( buf ); - - return( ret ); -} -#endif /* MBEDTLS_FS_IO */ - -#define BEFORE_COLON 14 -#define BC "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; - size_t n; - char *p; - char key_size_str[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, - csr->sig_opts ); - MBEDTLS_X509_SAFE_SNPRINTF; - - if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON, - mbedtls_pk_get_name( &csr->pk ) ) ) != 0 ) - { - return( ret ); - } - - ret = mbedtls_snprintf( p, n, "\n%s%-" BC "s: %d bits\n", prefix, key_size_str, - (int) mbedtls_pk_get_bitlen( &csr->pk ) ); - MBEDTLS_X509_SAFE_SNPRINTF; - - return( (int) ( size - n ) ); -} - -/* - * 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 ) -{ - mbedtls_x509_name *name_cur; - mbedtls_x509_name *name_prv; - - if( csr == NULL ) - return; - - mbedtls_pk_free( &csr->pk ); - -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) - mbedtls_free( csr->sig_opts ); -#endif - - name_cur = csr->subject.next; - while( name_cur != NULL ) - { - name_prv = name_cur; - name_cur = name_cur->next; - mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) ); - mbedtls_free( name_prv ); - } - - if( csr->raw.p != NULL ) - { - mbedtls_platform_zeroize( csr->raw.p, csr->raw.len ); - mbedtls_free( csr->raw.p ); - } - - mbedtls_platform_zeroize( csr, sizeof( mbedtls_x509_csr ) ); -} - -#endif /* MBEDTLS_X509_CSR_PARSE_C */ diff --git a/library/x509write_crt.c b/library/x509write_crt.c deleted file mode 100644 index b6cb745a3..000000000 --- a/library/x509write_crt.c +++ /dev/null @@ -1,495 +0,0 @@ -/* - * X.509 certificate writing - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -/* - * References: - * - certificates: RFC 5280, updated by RFC 6818 - * - CSRs: PKCS#10 v1.7 aka RFC 2986 - * - attributes: PKCS#9 v2.0 aka RFC 2985 - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_X509_CRT_WRITE_C) - -#include "mbedtls/x509_crt.h" -#include "mbedtls/oid.h" -#include "mbedtls/asn1write.h" -#include "mbedtls/sha1.h" -#include "mbedtls/platform_util.h" - -#include - -#if defined(MBEDTLS_PEM_WRITE_C) -#include "mbedtls/pem.h" -#endif /* MBEDTLS_PEM_WRITE_C */ - -void mbedtls_x509write_crt_init( mbedtls_x509write_cert *ctx ) -{ - memset( ctx, 0, sizeof( mbedtls_x509write_cert ) ); - - mbedtls_mpi_init( &ctx->serial ); - ctx->version = MBEDTLS_X509_CRT_VERSION_3; -} - -void mbedtls_x509write_crt_free( mbedtls_x509write_cert *ctx ) -{ - mbedtls_mpi_free( &ctx->serial ); - - 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 ) -{ - 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 ) -{ - return mbedtls_x509_string_to_names( &ctx->issuer, issuer_name ); -} - -int mbedtls_x509write_crt_set_serial( mbedtls_x509write_cert *ctx, const mbedtls_mpi *serial ) -{ - int ret; - - if( ( ret = mbedtls_mpi_copy( &ctx->serial, serial ) ) != 0 ) - return( ret ); - - 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_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; - 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 ), - 0, buf + sizeof(buf) - len, len ); -} - -#if defined(MBEDTLS_SHA1_C) -int mbedtls_x509write_crt_set_subject_key_identifier( mbedtls_x509write_cert *ctx ) -{ - int ret; - unsigned char buf[MBEDTLS_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */ - unsigned char *c = buf + sizeof(buf); - size_t len = 0; - - memset( buf, 0, sizeof(buf) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, ctx->subject_key ) ); - - ret = mbedtls_sha1_ret( buf + sizeof( buf ) - len, len, - buf + sizeof( buf ) - 20 ); - if( ret != 0 ) - return( ret ); - 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, MBEDTLS_ASN1_OCTET_STRING ) ); - - 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_authority_key_identifier( mbedtls_x509write_cert *ctx ) -{ - int ret; - unsigned char buf[MBEDTLS_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */ - unsigned char *c = buf + sizeof( buf ); - size_t len = 0; - - memset( buf, 0, sizeof(buf) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, ctx->issuer_key ) ); - - ret = mbedtls_sha1_ret( buf + sizeof( buf ) - len, len, - buf + sizeof( buf ) - 20 ); - if( ret != 0 ) - return( ret ); - 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, MBEDTLS_ASN1_CONTEXT_SPECIFIC | 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 ) ); - - 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 ); -} -#endif /* MBEDTLS_SHA1_C */ - -int mbedtls_x509write_crt_set_key_usage( mbedtls_x509write_cert *ctx, - unsigned int key_usage ) -{ - unsigned char buf[5], ku[2]; - unsigned char *c; - int ret; - 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; - ku[0] = (unsigned char)( key_usage ); - ku[1] = (unsigned char)( key_usage >> 8 ); - 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_ns_cert_type( mbedtls_x509write_cert *ctx, - unsigned char ns_cert_type ) -{ - unsigned char buf[4]; - unsigned char *c; - int ret; - - 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; - size_t len = 0; - - /* - * write MBEDTLS_ASN1_UTC_TIME if year < 2050 (2 bytes shorter) - */ - if( 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 (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - const char *sig_oid; - size_t sig_oid_len = 0; - unsigned char *c, *c2; - unsigned char hash[64]; - unsigned char sig[MBEDTLS_MPI_MAX_SIZE]; - unsigned char tmp_buf[2048]; - 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; - - /* - * Prepare data to be signed in tmp_buf - */ - c = tmp_buf + sizeof( tmp_buf ); - - /* 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_oid_get_oid_by_sig_alg( 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, tmp_buf, ctx->extensions ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC | - MBEDTLS_ASN1_CONSTRUCTED | 3 ) ); - } - - /* - * SubjectPublicKeyInfo - */ - MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_pk_write_pubkey_der( ctx->subject_key, - tmp_buf, c - tmp_buf ) ); - c -= pub_len; - len += pub_len; - - /* - * Subject ::= Name - */ - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, tmp_buf, ctx->subject ) ); - - /* - * Validity ::= SEQUENCE { - * notBefore Time, - * notAfter Time } - */ - sub_len = 0; - - MBEDTLS_ASN1_CHK_ADD( sub_len, x509_write_time( &c, tmp_buf, ctx->not_after, - MBEDTLS_X509_RFC5280_UTC_TIME_LEN ) ); - - MBEDTLS_ASN1_CHK_ADD( sub_len, x509_write_time( &c, tmp_buf, ctx->not_before, - MBEDTLS_X509_RFC5280_UTC_TIME_LEN ) ); - - len += sub_len; - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, sub_len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE ) ); - - /* - * Issuer ::= Name - */ - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, tmp_buf, ctx->issuer ) ); - - /* - * Signature ::= AlgorithmIdentifier - */ - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( &c, tmp_buf, - sig_oid, strlen( sig_oid ), 0 ) ); - - /* - * Serial ::= INTEGER - */ - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, tmp_buf, &ctx->serial ) ); - - /* - * 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, tmp_buf, ctx->version ) ); - len += sub_len; - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, sub_len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC | - MBEDTLS_ASN1_CONSTRUCTED | 0 ) ); - } - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE ) ); - - /* - * Make signature - */ - if( ( ret = mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, - len, hash ) ) != 0 ) - { - return( ret ); - } - - if( ( ret = mbedtls_pk_sign( ctx->issuer_key, ctx->md_alg, hash, 0, sig, &sig_len, - f_rng, p_rng ) ) != 0 ) - { - return( ret ); - } - - /* - * Write data to output buffer - */ - c2 = buf + size; - MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, mbedtls_x509_write_sig( &c2, buf, - sig_oid, sig_oid_len, sig, sig_len ) ); - - if( len > (size_t)( c2 - buf ) ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - c2 -= len; - memcpy( c2, c, len ); - - 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 ) ); - - 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 (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - unsigned char output_buf[4096]; - size_t olen = 0; - - if( ( ret = mbedtls_x509write_crt_der( crt, output_buf, sizeof(output_buf), - f_rng, p_rng ) ) < 0 ) - { - return( ret ); - } - - if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_CRT, PEM_END_CRT, - output_buf + sizeof(output_buf) - ret, - ret, buf, size, &olen ) ) != 0 ) - { - return( ret ); - } - - return( 0 ); -} -#endif /* MBEDTLS_PEM_WRITE_C */ - -#endif /* MBEDTLS_X509_CRT_WRITE_C */ diff --git a/library/x509write_csr.c b/library/x509write_csr.c deleted file mode 100644 index 8dc39e7a5..000000000 --- a/library/x509write_csr.c +++ /dev/null @@ -1,287 +0,0 @@ -/* - * X.509 Certificate Signing Request writing - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * 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. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -/* - * References: - * - CSRs: PKCS#10 v1.7 aka RFC 2986 - * - attributes: PKCS#9 v2.0 aka RFC 2985 - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_X509_CSR_WRITE_C) - -#include "mbedtls/x509_csr.h" -#include "mbedtls/oid.h" -#include "mbedtls/asn1write.h" -#include "mbedtls/platform_util.h" - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "psa/crypto.h" -#include "mbedtls/psa_util.h" -#endif - -#include -#include - -#if defined(MBEDTLS_PEM_WRITE_C) -#include "mbedtls/pem.h" -#endif - -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 ) -{ - 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 ) -{ - 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, - const unsigned char *val, size_t val_len ) -{ - return mbedtls_x509_set_extension( &ctx->extensions, oid, oid_len, - 0, val, val_len ); -} - -int mbedtls_x509write_csr_set_key_usage( mbedtls_x509write_csr *ctx, unsigned char key_usage ) -{ - unsigned char buf[4]; - unsigned char *c; - int ret; - - 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 ), - 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]; - unsigned char *c; - int ret; - - 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 ), - c, (size_t)ret ); - if( ret != 0 ) - return( ret ); - - return( 0 ); -} - -int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - const char *sig_oid; - size_t sig_oid_len = 0; - unsigned char *c, *c2; - unsigned char hash[64]; - unsigned char sig[MBEDTLS_MPI_MAX_SIZE]; - unsigned char tmp_buf[2048]; - size_t pub_len = 0, sig_and_oid_len = 0, sig_len; - size_t len = 0; - mbedtls_pk_type_t pk_alg; -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_hash_operation_t hash_operation = PSA_HASH_OPERATION_INIT; - size_t hash_len; - psa_algorithm_t hash_alg = mbedtls_psa_translate_md( ctx->md_alg ); -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - /* - * Prepare data to be signed in tmp_buf - */ - c = tmp_buf + sizeof( tmp_buf ); - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_extensions( &c, tmp_buf, ctx->extensions ) ); - - if( len ) - { - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE ) ); - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SET ) ); - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( &c, tmp_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, tmp_buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE ) ); - } - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ); - - MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_pk_write_pubkey_der( ctx->key, - tmp_buf, c - tmp_buf ) ); - c -= pub_len; - len += pub_len; - - /* - * Subject ::= Name - */ - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, tmp_buf, ctx->subject ) ); - - /* - * Version ::= INTEGER { v1(0), v2(1), v3(2) } - */ - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, tmp_buf, 0 ) ); - - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); - MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE ) ); - - /* - * Prepare signature - * Note: hash errors can happen only after an internal error - */ -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if( psa_hash_setup( &hash_operation, hash_alg ) != PSA_SUCCESS ) - return( MBEDTLS_ERR_X509_FATAL_ERROR ); - - if( psa_hash_update( &hash_operation, c, len ) != PSA_SUCCESS ) - return( MBEDTLS_ERR_X509_FATAL_ERROR ); - - if( psa_hash_finish( &hash_operation, hash, sizeof( hash ), &hash_len ) - != PSA_SUCCESS ) - { - return( MBEDTLS_ERR_X509_FATAL_ERROR ); - } -#else /* MBEDTLS_USE_PSA_CRYPTO */ - mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, len, hash ); -#endif - if( ( ret = mbedtls_pk_sign( ctx->key, ctx->md_alg, hash, 0, sig, &sig_len, - f_rng, p_rng ) ) != 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_oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg, - &sig_oid, &sig_oid_len ) ) != 0 ) - { - return( ret ); - } - - /* - * Write data to output buffer - */ - c2 = buf + size; - MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, mbedtls_x509_write_sig( &c2, buf, - sig_oid, sig_oid_len, sig, sig_len ) ); - - if( len > (size_t)( c2 - buf ) ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - - c2 -= len; - memcpy( c2, c, len ); - - 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 ) ); - - return( (int) len ); -} - -#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 (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ) -{ - int ret; - unsigned char output_buf[4096]; - size_t olen = 0; - - if( ( ret = mbedtls_x509write_csr_der( ctx, output_buf, sizeof(output_buf), - f_rng, p_rng ) ) < 0 ) - { - return( ret ); - } - - if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_CSR, PEM_END_CSR, - output_buf + sizeof(output_buf) - ret, - ret, buf, size, &olen ) ) != 0 ) - { - return( ret ); - } - - return( 0 ); -} -#endif /* MBEDTLS_PEM_WRITE_C */ - -#endif /* MBEDTLS_X509_CSR_WRITE_C */ diff --git a/programs/test/cpp_dummy_build.cpp b/programs/test/cpp_dummy_build.cpp index f33038f6d..c1dc7433d 100644 --- a/programs/test/cpp_dummy_build.cpp +++ b/programs/test/cpp_dummy_build.cpp @@ -46,7 +46,6 @@ #include "mbedtls/cipher_internal.h" #include "mbedtls/cmac.h" #include "mbedtls/ctr_drbg.h" -#include "mbedtls/debug.h" #include "mbedtls/des.h" #include "mbedtls/dhm.h" #include "mbedtls/ecdh.h" @@ -66,15 +65,12 @@ #include "mbedtls/md4.h" #include "mbedtls/md5.h" #include "mbedtls/md_internal.h" -#include "mbedtls/net.h" -#include "mbedtls/net_sockets.h" #include "mbedtls/nist_kw.h" #include "mbedtls/oid.h" #include "mbedtls/padlock.h" #include "mbedtls/pem.h" #include "mbedtls/pk.h" #include "mbedtls/pk_internal.h" -#include "mbedtls/pkcs11.h" #include "mbedtls/pkcs12.h" #include "mbedtls/pkcs5.h" #include "mbedtls/platform_time.h" @@ -87,12 +83,6 @@ #include "mbedtls/sha1.h" #include "mbedtls/sha256.h" #include "mbedtls/sha512.h" -#include "mbedtls/ssl.h" -#include "mbedtls/ssl_cache.h" -#include "mbedtls/ssl_ciphersuites.h" -#include "mbedtls/ssl_cookie.h" -#include "mbedtls/ssl_internal.h" -#include "mbedtls/ssl_ticket.h" #include "mbedtls/threading.h" #include "mbedtls/timing.h" #include "mbedtls/version.h" diff --git a/programs/test/query_config.c b/programs/test/query_config.c index 94c8ec16d..fc25353fa 100644 --- a/programs/test/query_config.c +++ b/programs/test/query_config.c @@ -53,7 +53,6 @@ #include "mbedtls/cipher.h" #include "mbedtls/cmac.h" #include "mbedtls/ctr_drbg.h" -#include "mbedtls/debug.h" #include "mbedtls/des.h" #include "mbedtls/dhm.h" #include "mbedtls/ecdh.h" @@ -72,13 +71,11 @@ #include "mbedtls/md4.h" #include "mbedtls/md5.h" #include "mbedtls/memory_buffer_alloc.h" -#include "mbedtls/net_sockets.h" #include "mbedtls/nist_kw.h" #include "mbedtls/oid.h" #include "mbedtls/padlock.h" #include "mbedtls/pem.h" #include "mbedtls/pk.h" -#include "mbedtls/pkcs11.h" #include "mbedtls/pkcs12.h" #include "mbedtls/pkcs5.h" #include "mbedtls/platform_time.h" @@ -89,19 +86,9 @@ #include "mbedtls/sha1.h" #include "mbedtls/sha256.h" #include "mbedtls/sha512.h" -#include "mbedtls/ssl.h" -#include "mbedtls/ssl_cache.h" -#include "mbedtls/ssl_ciphersuites.h" -#include "mbedtls/ssl_cookie.h" -#include "mbedtls/ssl_internal.h" -#include "mbedtls/ssl_ticket.h" #include "mbedtls/threading.h" #include "mbedtls/timing.h" #include "mbedtls/version.h" -#include "mbedtls/x509.h" -#include "mbedtls/x509_crl.h" -#include "mbedtls/x509_crt.h" -#include "mbedtls/x509_csr.h" #include "mbedtls/xtea.h" #include diff --git a/scripts/data_files/query_config.fmt b/scripts/data_files/query_config.fmt index 064da4c38..600f13030 100644 --- a/scripts/data_files/query_config.fmt +++ b/scripts/data_files/query_config.fmt @@ -53,7 +53,6 @@ #include "mbedtls/cipher.h" #include "mbedtls/cmac.h" #include "mbedtls/ctr_drbg.h" -#include "mbedtls/debug.h" #include "mbedtls/des.h" #include "mbedtls/dhm.h" #include "mbedtls/ecdh.h" @@ -72,13 +71,11 @@ #include "mbedtls/md4.h" #include "mbedtls/md5.h" #include "mbedtls/memory_buffer_alloc.h" -#include "mbedtls/net_sockets.h" #include "mbedtls/nist_kw.h" #include "mbedtls/oid.h" #include "mbedtls/padlock.h" #include "mbedtls/pem.h" #include "mbedtls/pk.h" -#include "mbedtls/pkcs11.h" #include "mbedtls/pkcs12.h" #include "mbedtls/pkcs5.h" #include "mbedtls/platform_time.h" @@ -89,19 +86,9 @@ #include "mbedtls/sha1.h" #include "mbedtls/sha256.h" #include "mbedtls/sha512.h" -#include "mbedtls/ssl.h" -#include "mbedtls/ssl_cache.h" -#include "mbedtls/ssl_ciphersuites.h" -#include "mbedtls/ssl_cookie.h" -#include "mbedtls/ssl_internal.h" -#include "mbedtls/ssl_ticket.h" #include "mbedtls/threading.h" #include "mbedtls/timing.h" #include "mbedtls/version.h" -#include "mbedtls/x509.h" -#include "mbedtls/x509_crl.h" -#include "mbedtls/x509_crt.h" -#include "mbedtls/x509_csr.h" #include "mbedtls/xtea.h" #include diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj index c56e976a7..07c80e84f 100644 --- a/visualc/VS2010/mbedTLS.vcxproj +++ b/visualc/VS2010/mbedTLS.vcxproj @@ -168,7 +168,6 @@ - @@ -189,15 +188,12 @@ - - - @@ -211,19 +207,9 @@ - - - - - - - - - - @@ -255,14 +241,12 @@ - - @@ -283,14 +267,12 @@ - - @@ -308,24 +290,10 @@ - - - - - - - - - - - - - -