early-access version 1503
This commit is contained in:
@@ -21,15 +21,16 @@ if(TEST_CPP)
|
||||
target_link_libraries(cpp_dummy_build ${libs})
|
||||
endif()
|
||||
|
||||
add_executable(ssl_cert_test ssl_cert_test.c)
|
||||
target_link_libraries(ssl_cert_test ${libs})
|
||||
|
||||
add_executable(udp_proxy udp_proxy.c)
|
||||
target_link_libraries(udp_proxy ${libs})
|
||||
|
||||
add_executable(zeroize zeroize.c)
|
||||
target_link_libraries(zeroize ${libs})
|
||||
|
||||
install(TARGETS selftest benchmark ssl_cert_test udp_proxy
|
||||
add_executable(query_compile_time_config query_compile_time_config.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../ssl/query_config.c)
|
||||
target_link_libraries(query_compile_time_config ${libs})
|
||||
|
||||
install(TARGETS selftest benchmark udp_proxy query_compile_time_config
|
||||
DESTINATION "bin"
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
||||
|
61
externals/mbedtls/programs/test/benchmark.c
vendored
61
externals/mbedtls/programs/test/benchmark.c
vendored
@@ -1,8 +1,31 @@
|
||||
/*
|
||||
* Benchmark demonstration program
|
||||
*
|
||||
* Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: GPL-2.0
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*
|
||||
* This file is provided under the Apache License 2.0, or the
|
||||
* GNU General Public License v2.0 or later.
|
||||
*
|
||||
* **********
|
||||
* Apache License 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.
|
||||
*
|
||||
* **********
|
||||
*
|
||||
* **********
|
||||
* GNU General Public License v2.0 or later:
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -18,7 +41,7 @@
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
||||
* **********
|
||||
*/
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
@@ -31,17 +54,21 @@
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define mbedtls_exit exit
|
||||
#define mbedtls_printf printf
|
||||
#define mbedtls_snprintf snprintf
|
||||
#define mbedtls_free free
|
||||
#define mbedtls_exit exit
|
||||
#define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS
|
||||
#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE
|
||||
#endif
|
||||
|
||||
#if !defined(MBEDTLS_TIMING_C)
|
||||
int main( void )
|
||||
{
|
||||
mbedtls_printf("MBEDTLS_TIMING_C not defined.\n");
|
||||
return( 0 );
|
||||
mbedtls_exit( 0 );
|
||||
}
|
||||
#else
|
||||
|
||||
@@ -153,6 +180,16 @@ do { \
|
||||
|
||||
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && defined(MBEDTLS_MEMORY_DEBUG)
|
||||
|
||||
/* How much space to reserve for the title when printing heap usage results.
|
||||
* Updated manually as the output of the following command:
|
||||
*
|
||||
* sed -n 's/.*[T]IME_PUBLIC.*"\(.*\)",/\1/p' programs/test/benchmark.c |
|
||||
* awk '{print length+2}' | sort -rn | head -n1
|
||||
*
|
||||
* This computes the maximum length of a title +2 (because we appends "/s").
|
||||
* (If the value is too small, the only consequence is poor alignement.) */
|
||||
#define TITLE_SPACE 11
|
||||
|
||||
#define MEMORY_MEASURE_INIT \
|
||||
size_t max_used, max_blocks, max_bytes; \
|
||||
size_t prv_used, prv_blocks; \
|
||||
@@ -161,7 +198,8 @@ do { \
|
||||
|
||||
#define MEMORY_MEASURE_PRINT( title_len ) \
|
||||
mbedtls_memory_buffer_alloc_max_get( &max_used, &max_blocks ); \
|
||||
for( ii = 12 - title_len; ii != 0; ii-- ) mbedtls_printf( " " ); \
|
||||
ii = TITLE_SPACE > (title_len) ? TITLE_SPACE - (title_len) : 1; \
|
||||
while( ii-- ) mbedtls_printf( " " ); \
|
||||
max_used -= prv_used; \
|
||||
max_blocks -= prv_blocks; \
|
||||
max_bytes = max_used + MEM_BLOCK_OVERHEAD * max_blocks; \
|
||||
@@ -256,6 +294,7 @@ typedef struct {
|
||||
rsa, dhm, ecdsa, ecdh;
|
||||
} todo_list;
|
||||
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
int i;
|
||||
@@ -671,12 +710,13 @@ int main( int argc, char *argv[] )
|
||||
mbedtls_ctr_drbg_context ctr_drbg;
|
||||
|
||||
mbedtls_ctr_drbg_init( &ctr_drbg );
|
||||
|
||||
if( mbedtls_ctr_drbg_seed( &ctr_drbg, myrand, NULL, NULL, 0 ) != 0 )
|
||||
mbedtls_exit(1);
|
||||
TIME_AND_TSC( "CTR_DRBG (NOPR)",
|
||||
mbedtls_ctr_drbg_random( &ctr_drbg, buf, BUFSIZE ) );
|
||||
mbedtls_ctr_drbg_free( &ctr_drbg );
|
||||
|
||||
mbedtls_ctr_drbg_init( &ctr_drbg );
|
||||
if( mbedtls_ctr_drbg_seed( &ctr_drbg, myrand, NULL, NULL, 0 ) != 0 )
|
||||
mbedtls_exit(1);
|
||||
mbedtls_ctr_drbg_set_prediction_resistance( &ctr_drbg, MBEDTLS_CTR_DRBG_PR_ON );
|
||||
@@ -702,7 +742,6 @@ int main( int argc, char *argv[] )
|
||||
mbedtls_exit(1);
|
||||
TIME_AND_TSC( "HMAC_DRBG SHA-1 (NOPR)",
|
||||
mbedtls_hmac_drbg_random( &hmac_drbg, buf, BUFSIZE ) );
|
||||
mbedtls_hmac_drbg_free( &hmac_drbg );
|
||||
|
||||
if( mbedtls_hmac_drbg_seed( &hmac_drbg, md_info, myrand, NULL, NULL, 0 ) != 0 )
|
||||
mbedtls_exit(1);
|
||||
@@ -710,7 +749,6 @@ int main( int argc, char *argv[] )
|
||||
MBEDTLS_HMAC_DRBG_PR_ON );
|
||||
TIME_AND_TSC( "HMAC_DRBG SHA-1 (PR)",
|
||||
mbedtls_hmac_drbg_random( &hmac_drbg, buf, BUFSIZE ) );
|
||||
mbedtls_hmac_drbg_free( &hmac_drbg );
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SHA256_C)
|
||||
@@ -721,7 +759,6 @@ int main( int argc, char *argv[] )
|
||||
mbedtls_exit(1);
|
||||
TIME_AND_TSC( "HMAC_DRBG SHA-256 (NOPR)",
|
||||
mbedtls_hmac_drbg_random( &hmac_drbg, buf, BUFSIZE ) );
|
||||
mbedtls_hmac_drbg_free( &hmac_drbg );
|
||||
|
||||
if( mbedtls_hmac_drbg_seed( &hmac_drbg, md_info, myrand, NULL, NULL, 0 ) != 0 )
|
||||
mbedtls_exit(1);
|
||||
@@ -729,8 +766,8 @@ int main( int argc, char *argv[] )
|
||||
MBEDTLS_HMAC_DRBG_PR_ON );
|
||||
TIME_AND_TSC( "HMAC_DRBG SHA-256 (PR)",
|
||||
mbedtls_hmac_drbg_random( &hmac_drbg, buf, BUFSIZE ) );
|
||||
mbedtls_hmac_drbg_free( &hmac_drbg );
|
||||
#endif
|
||||
mbedtls_hmac_drbg_free( &hmac_drbg );
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -867,7 +904,7 @@ int main( int argc, char *argv[] )
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ECDH_C)
|
||||
#if defined(MBEDTLS_ECDH_C) && defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
|
||||
if( todo.ecdh )
|
||||
{
|
||||
mbedtls_ecdh_context ecdh;
|
||||
@@ -999,7 +1036,7 @@ int main( int argc, char *argv[] )
|
||||
fflush( stdout ); getchar();
|
||||
#endif
|
||||
|
||||
return( 0 );
|
||||
mbedtls_exit( 0 );
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_TIMING_C */
|
||||
|
@@ -2,8 +2,31 @@
|
||||
* This program is a dummy C++ program to ensure Mbed TLS library header files
|
||||
* can be included and built with a C++ compiler.
|
||||
*
|
||||
* Copyright (C) 2018, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: GPL-2.0
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*
|
||||
* This file is provided under the Apache License 2.0, or the
|
||||
* GNU General Public License v2.0 or later.
|
||||
*
|
||||
* **********
|
||||
* Apache License 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.
|
||||
*
|
||||
* **********
|
||||
*
|
||||
* **********
|
||||
* GNU General Public License v2.0 or later:
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -19,7 +42,7 @@
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
||||
* **********
|
||||
*/
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
|
81
externals/mbedtls/programs/test/query_compile_time_config.c
vendored
Executable file
81
externals/mbedtls/programs/test/query_compile_time_config.c
vendored
Executable file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Query the Mbed TLS compile time configuration
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*
|
||||
* This file is provided under the Apache License 2.0, or the
|
||||
* GNU General Public License v2.0 or later.
|
||||
*
|
||||
* **********
|
||||
* Apache License 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.
|
||||
*
|
||||
* **********
|
||||
*
|
||||
* **********
|
||||
* GNU General Public License v2.0 or later:
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* **********
|
||||
*/
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include "mbedtls/config.h"
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define mbedtls_printf printf
|
||||
#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE
|
||||
#endif
|
||||
|
||||
#define USAGE \
|
||||
"usage: %s <MBEDTLS_CONFIG>\n\n" \
|
||||
"This program takes one command line argument which corresponds to\n" \
|
||||
"the string representation of a Mbed TLS compile time configuration.\n" \
|
||||
"The value 0 will be returned if this configuration is defined in the\n" \
|
||||
"Mbed TLS build and the macro expansion of that configuration will be\n" \
|
||||
"printed (if any). Otherwise, 1 will be returned.\n"
|
||||
|
||||
int query_config( const char *config );
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
if ( argc != 2 )
|
||||
{
|
||||
mbedtls_printf( USAGE, argv[0] );
|
||||
return( MBEDTLS_EXIT_FAILURE );
|
||||
}
|
||||
|
||||
return( query_config( argv[1] ) );
|
||||
}
|
119
externals/mbedtls/programs/test/selftest.c
vendored
119
externals/mbedtls/programs/test/selftest.c
vendored
@@ -1,8 +1,31 @@
|
||||
/*
|
||||
* Self-test demonstration program
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: GPL-2.0
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*
|
||||
* This file is provided under the Apache License 2.0, or the
|
||||
* GNU General Public License v2.0 or later.
|
||||
*
|
||||
* **********
|
||||
* Apache License 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.
|
||||
*
|
||||
* **********
|
||||
*
|
||||
* **********
|
||||
* GNU General Public License v2.0 or later:
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -18,7 +41,7 @@
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
||||
* **********
|
||||
*/
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
@@ -68,6 +91,8 @@
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#define mbedtls_printf printf
|
||||
#define mbedtls_snprintf snprintf
|
||||
#define mbedtls_exit exit
|
||||
@@ -79,7 +104,88 @@
|
||||
#include "mbedtls/memory_buffer_alloc.h"
|
||||
#endif
|
||||
|
||||
static int test_snprintf( size_t n, const char ref_buf[10], int ref_ret )
|
||||
|
||||
#if defined MBEDTLS_SELF_TEST
|
||||
/* Sanity check for malloc. This is not expected to fail, and is rather
|
||||
* intended to display potentially useful information about the platform,
|
||||
* in particular the behavior of malloc(0). */
|
||||
static int calloc_self_test( int verbose )
|
||||
{
|
||||
int failures = 0;
|
||||
void *empty1 = mbedtls_calloc( 0, 1 );
|
||||
void *empty2 = mbedtls_calloc( 0, 1 );
|
||||
void *buffer1 = mbedtls_calloc( 1, 1 );
|
||||
void *buffer2 = mbedtls_calloc( 1, 1 );
|
||||
uintptr_t old_buffer1;
|
||||
|
||||
if( empty1 == NULL && empty2 == NULL )
|
||||
{
|
||||
if( verbose )
|
||||
mbedtls_printf( " CALLOC(0): passed (NULL)\n" );
|
||||
}
|
||||
else if( empty1 == NULL || empty2 == NULL )
|
||||
{
|
||||
if( verbose )
|
||||
mbedtls_printf( " CALLOC(0): failed (mix of NULL and non-NULL)\n" );
|
||||
++failures;
|
||||
}
|
||||
else if( empty1 == empty2 )
|
||||
{
|
||||
if( verbose )
|
||||
mbedtls_printf( " CALLOC(0): passed (same non-null)\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( verbose )
|
||||
mbedtls_printf( " CALLOC(0): passed (distinct non-null)\n" );
|
||||
}
|
||||
|
||||
if( buffer1 == NULL || buffer2 == NULL )
|
||||
{
|
||||
if( verbose )
|
||||
mbedtls_printf( " CALLOC(1): failed (NULL)\n" );
|
||||
++failures;
|
||||
}
|
||||
else if( buffer1 == buffer2 )
|
||||
{
|
||||
if( verbose )
|
||||
mbedtls_printf( " CALLOC(1): failed (same buffer twice)\n" );
|
||||
++failures;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( verbose )
|
||||
mbedtls_printf( " CALLOC(1): passed\n" );
|
||||
}
|
||||
|
||||
old_buffer1 = (uintptr_t) buffer1;
|
||||
mbedtls_free( buffer1 );
|
||||
buffer1 = mbedtls_calloc( 1, 1 );
|
||||
if( buffer1 == NULL )
|
||||
{
|
||||
if( verbose )
|
||||
mbedtls_printf( " CALLOC(1 again): failed (NULL)\n" );
|
||||
++failures;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( verbose )
|
||||
mbedtls_printf( " CALLOC(1 again): passed (%s address)\n",
|
||||
(uintptr_t) old_buffer1 == (uintptr_t) buffer1 ?
|
||||
"same" : "different" );
|
||||
}
|
||||
|
||||
if( verbose )
|
||||
mbedtls_printf( "\n" );
|
||||
mbedtls_free( empty1 );
|
||||
mbedtls_free( empty2 );
|
||||
mbedtls_free( buffer1 );
|
||||
mbedtls_free( buffer2 );
|
||||
return( failures );
|
||||
}
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
static int test_snprintf( size_t n, const char *ref_buf, int ref_ret )
|
||||
{
|
||||
int ret;
|
||||
char buf[10] = "xxxxxxxxx";
|
||||
@@ -175,6 +281,7 @@ typedef struct
|
||||
|
||||
const selftest_t selftests[] =
|
||||
{
|
||||
{"calloc", calloc_self_test},
|
||||
#if defined(MBEDTLS_MD2_C)
|
||||
{"md2", mbedtls_md2_self_test},
|
||||
#endif
|
||||
@@ -418,7 +525,5 @@ int main( int argc, char *argv[] )
|
||||
if( suites_failed > 0)
|
||||
mbedtls_exit( MBEDTLS_EXIT_FAILURE );
|
||||
|
||||
/* return() is here to prevent compiler warnings */
|
||||
return( MBEDTLS_EXIT_SUCCESS );
|
||||
mbedtls_exit( MBEDTLS_EXIT_SUCCESS );
|
||||
}
|
||||
|
||||
|
273
externals/mbedtls/programs/test/udp_proxy.c
vendored
273
externals/mbedtls/programs/test/udp_proxy.c
vendored
@@ -1,8 +1,31 @@
|
||||
/*
|
||||
* UDP proxy: emulate an unreliable UDP connexion for DTLS testing
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: GPL-2.0
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*
|
||||
* This file is provided under the Apache License 2.0, or the
|
||||
* GNU General Public License v2.0 or later.
|
||||
*
|
||||
* **********
|
||||
* Apache License 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.
|
||||
*
|
||||
* **********
|
||||
*
|
||||
* **********
|
||||
* GNU General Public License v2.0 or later:
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -18,7 +41,7 @@
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
||||
* **********
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -42,6 +65,9 @@
|
||||
#define mbedtls_time time
|
||||
#define mbedtls_time_t time_t
|
||||
#define mbedtls_printf printf
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#define mbedtls_exit exit
|
||||
#define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS
|
||||
#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
@@ -50,7 +76,7 @@
|
||||
int main( void )
|
||||
{
|
||||
mbedtls_printf( "MBEDTLS_NET_C not defined.\n" );
|
||||
return( 0 );
|
||||
mbedtls_exit( 0 );
|
||||
}
|
||||
#else
|
||||
|
||||
@@ -108,6 +134,21 @@ int main( void )
|
||||
" delay=%%d default: 0 (no delayed packets)\n" \
|
||||
" delay about 1:N packets randomly\n" \
|
||||
" delay_ccs=0/1 default: 0 (don't delay ChangeCipherSpec)\n" \
|
||||
" delay_cli=%%s Handshake message from client that should be\n"\
|
||||
" delayed. Possible values are 'ClientHello',\n" \
|
||||
" 'Certificate', 'CertificateVerify', and\n" \
|
||||
" 'ClientKeyExchange'.\n" \
|
||||
" May be used multiple times, even for the same\n"\
|
||||
" message, in which case the respective message\n"\
|
||||
" gets delayed multiple times.\n" \
|
||||
" delay_srv=%%s Handshake message from server that should be\n"\
|
||||
" delayed. Possible values are 'HelloRequest',\n"\
|
||||
" 'ServerHello', 'ServerHelloDone', 'Certificate'\n"\
|
||||
" 'ServerKeyExchange', 'NewSessionTicket',\n"\
|
||||
" 'HelloVerifyRequest' and ''CertificateRequest'.\n"\
|
||||
" May be used multiple times, even for the same\n"\
|
||||
" message, in which case the respective message\n"\
|
||||
" gets delayed multiple times.\n" \
|
||||
" drop=%%d default: 0 (no dropped packets)\n" \
|
||||
" drop about 1:N packets randomly\n" \
|
||||
" mtu=%%d default: 0 (unlimited)\n" \
|
||||
@@ -115,6 +156,7 @@ int main( void )
|
||||
" bad_ad=0/1 default: 0 (don't add bad ApplicationData)\n" \
|
||||
" protect_hvr=0/1 default: 0 (don't protect HelloVerifyRequest)\n" \
|
||||
" protect_len=%%d default: (don't protect packets of this size)\n" \
|
||||
" inject_clihlo=0/1 default: 0 (don't inject fake ClientHello)\n" \
|
||||
"\n" \
|
||||
" seed=%%d default: (use current time)\n" \
|
||||
USAGE_PACK \
|
||||
@@ -123,6 +165,9 @@ int main( void )
|
||||
/*
|
||||
* global options
|
||||
*/
|
||||
|
||||
#define MAX_DELAYED_HS 10
|
||||
|
||||
static struct options
|
||||
{
|
||||
const char *server_addr; /* address to forward packets to */
|
||||
@@ -133,11 +178,18 @@ static struct options
|
||||
int duplicate; /* duplicate 1 in N packets (none if 0) */
|
||||
int delay; /* delay 1 packet in N (none if 0) */
|
||||
int delay_ccs; /* delay ChangeCipherSpec */
|
||||
char* delay_cli[MAX_DELAYED_HS]; /* handshake types of messages from
|
||||
* client that should be delayed. */
|
||||
uint8_t delay_cli_cnt; /* Number of entries in delay_cli. */
|
||||
char* delay_srv[MAX_DELAYED_HS]; /* handshake types of messages from
|
||||
* server that should be delayed. */
|
||||
uint8_t delay_srv_cnt; /* Number of entries in delay_srv. */
|
||||
int drop; /* drop 1 packet in N (none if 0) */
|
||||
int mtu; /* drop packets larger than this */
|
||||
int bad_ad; /* inject corrupted ApplicationData record */
|
||||
int protect_hvr; /* never drop or delay HelloVerifyRequest */
|
||||
int protect_len; /* never drop/delay packet of the given size*/
|
||||
int inject_clihlo; /* inject fake ClientHello after handshake */
|
||||
unsigned pack; /* merge packets into single datagram for
|
||||
* at most \c merge milliseconds if > 0 */
|
||||
unsigned int seed; /* seed for "random" events */
|
||||
@@ -166,6 +218,11 @@ static void get_options( int argc, char *argv[] )
|
||||
opt.pack = DFL_PACK;
|
||||
/* Other members default to 0 */
|
||||
|
||||
opt.delay_cli_cnt = 0;
|
||||
opt.delay_srv_cnt = 0;
|
||||
memset( opt.delay_cli, 0, sizeof( opt.delay_cli ) );
|
||||
memset( opt.delay_srv, 0, sizeof( opt.delay_srv ) );
|
||||
|
||||
for( i = 1; i < argc; i++ )
|
||||
{
|
||||
p = argv[i];
|
||||
@@ -199,6 +256,43 @@ static void get_options( int argc, char *argv[] )
|
||||
if( opt.delay_ccs < 0 || opt.delay_ccs > 1 )
|
||||
exit_usage( p, q );
|
||||
}
|
||||
else if( strcmp( p, "delay_cli" ) == 0 ||
|
||||
strcmp( p, "delay_srv" ) == 0 )
|
||||
{
|
||||
uint8_t *delay_cnt;
|
||||
char **delay_list;
|
||||
size_t len;
|
||||
char *buf;
|
||||
|
||||
if( strcmp( p, "delay_cli" ) == 0 )
|
||||
{
|
||||
delay_cnt = &opt.delay_cli_cnt;
|
||||
delay_list = opt.delay_cli;
|
||||
}
|
||||
else
|
||||
{
|
||||
delay_cnt = &opt.delay_srv_cnt;
|
||||
delay_list = opt.delay_srv;
|
||||
}
|
||||
|
||||
if( *delay_cnt == MAX_DELAYED_HS )
|
||||
{
|
||||
mbedtls_printf( " too many uses of %s: only %d allowed\n",
|
||||
p, MAX_DELAYED_HS );
|
||||
exit_usage( p, NULL );
|
||||
}
|
||||
|
||||
len = strlen( q );
|
||||
buf = mbedtls_calloc( 1, len + 1 );
|
||||
if( buf == NULL )
|
||||
{
|
||||
mbedtls_printf( " Allocation failure\n" );
|
||||
exit( 1 );
|
||||
}
|
||||
memcpy( buf, q, len + 1 );
|
||||
|
||||
delay_list[ (*delay_cnt)++ ] = buf;
|
||||
}
|
||||
else if( strcmp( p, "drop" ) == 0 )
|
||||
{
|
||||
opt.drop = atoi( q );
|
||||
@@ -238,6 +332,12 @@ static void get_options( int argc, char *argv[] )
|
||||
if( opt.protect_len < 0 )
|
||||
exit_usage( p, q );
|
||||
}
|
||||
else if( strcmp( p, "inject_clihlo" ) == 0 )
|
||||
{
|
||||
opt.inject_clihlo = atoi( q );
|
||||
if( opt.inject_clihlo < 0 || opt.inject_clihlo > 1 )
|
||||
exit_usage( p, q );
|
||||
}
|
||||
else if( strcmp( p, "seed" ) == 0 )
|
||||
{
|
||||
opt.seed = atoi( q );
|
||||
@@ -437,11 +537,41 @@ void print_packet( const packet *p, const char *why )
|
||||
fflush( stdout );
|
||||
}
|
||||
|
||||
/*
|
||||
* In order to test the server's behaviour when receiving a ClientHello after
|
||||
* the connection is established (this could be a hard reset from the client,
|
||||
* but the server must not drop the existing connection before establishing
|
||||
* client reachability, see RFC 6347 Section 4.2.8), we memorize the first
|
||||
* ClientHello we see (which can't have a cookie), then replay it after the
|
||||
* first ApplicationData record - then we're done.
|
||||
*
|
||||
* This is controlled by the inject_clihlo option.
|
||||
*
|
||||
* We want an explicit state and a place to store the packet.
|
||||
*/
|
||||
typedef enum {
|
||||
ICH_INIT, /* haven't seen the first ClientHello yet */
|
||||
ICH_CACHED, /* cached the initial ClientHello */
|
||||
ICH_INJECTED, /* ClientHello already injected, done */
|
||||
} inject_clihlo_state_t;
|
||||
|
||||
static inject_clihlo_state_t inject_clihlo_state;
|
||||
static packet initial_clihlo;
|
||||
|
||||
int send_packet( const packet *p, const char *why )
|
||||
{
|
||||
int ret;
|
||||
mbedtls_net_context *dst = p->dst;
|
||||
|
||||
/* save initial ClientHello? */
|
||||
if( opt.inject_clihlo != 0 &&
|
||||
inject_clihlo_state == ICH_INIT &&
|
||||
strcmp( p->type, "ClientHello" ) == 0 )
|
||||
{
|
||||
memcpy( &initial_clihlo, p, sizeof( packet ) );
|
||||
inject_clihlo_state = ICH_CACHED;
|
||||
}
|
||||
|
||||
/* insert corrupted ApplicationData record? */
|
||||
if( opt.bad_ad &&
|
||||
strcmp( p->type, "ApplicationData" ) == 0 )
|
||||
@@ -487,14 +617,57 @@ int send_packet( const packet *p, const char *why )
|
||||
}
|
||||
}
|
||||
|
||||
/* Inject ClientHello after first ApplicationData */
|
||||
if( opt.inject_clihlo != 0 &&
|
||||
inject_clihlo_state == ICH_CACHED &&
|
||||
strcmp( p->type, "ApplicationData" ) == 0 )
|
||||
{
|
||||
print_packet( &initial_clihlo, "injected" );
|
||||
|
||||
if( ( ret = dispatch_data( dst, initial_clihlo.buf,
|
||||
initial_clihlo.len ) ) <= 0 )
|
||||
{
|
||||
mbedtls_printf( " ! dispatch returned %d\n", ret );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
inject_clihlo_state = ICH_INJECTED;
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static packet prev;
|
||||
#define MAX_DELAYED_MSG 5
|
||||
static size_t prev_len;
|
||||
static packet prev[MAX_DELAYED_MSG];
|
||||
|
||||
void clear_pending( void )
|
||||
{
|
||||
memset( &prev, 0, sizeof( packet ) );
|
||||
memset( &prev, 0, sizeof( prev ) );
|
||||
prev_len = 0;
|
||||
}
|
||||
|
||||
void delay_packet( packet *delay )
|
||||
{
|
||||
if( prev_len == MAX_DELAYED_MSG )
|
||||
return;
|
||||
|
||||
memcpy( &prev[prev_len++], delay, sizeof( packet ) );
|
||||
}
|
||||
|
||||
int send_delayed()
|
||||
{
|
||||
uint8_t offset;
|
||||
int ret;
|
||||
for( offset = 0; offset < prev_len; offset++ )
|
||||
{
|
||||
ret = send_packet( &prev[offset], "delayed" );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
}
|
||||
|
||||
clear_pending();
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -506,32 +679,17 @@ void clear_pending( void )
|
||||
static unsigned char dropped[2048] = { 0 };
|
||||
#define DROP_MAX 2
|
||||
|
||||
/*
|
||||
* OpenSSL groups packets in a datagram the first time it sends them, but not
|
||||
* when it resends them. Count every record as seen the first time.
|
||||
*/
|
||||
/* We only drop packets at the level of entire datagrams, not at the level
|
||||
* of records. In particular, if the peer changes the way it packs multiple
|
||||
* records into a single datagram, we don't necessarily count the number of
|
||||
* times a record has been dropped correctly. However, the only known reason
|
||||
* why a peer would change datagram packing is disabling the latter on
|
||||
* retransmission, in which case we'd drop involved records at most
|
||||
* DROP_MAX + 1 times. */
|
||||
void update_dropped( const packet *p )
|
||||
{
|
||||
size_t id = p->len % sizeof( dropped );
|
||||
const unsigned char *end = p->buf + p->len;
|
||||
const unsigned char *cur = p->buf;
|
||||
size_t len = ( ( cur[11] << 8 ) | cur[12] ) + 13;
|
||||
|
||||
++dropped[id];
|
||||
|
||||
/* Avoid counting single record twice */
|
||||
if( len == p->len )
|
||||
return;
|
||||
|
||||
while( cur < end )
|
||||
{
|
||||
len = ( ( cur[11] << 8 ) | cur[12] ) + 13;
|
||||
|
||||
id = len % sizeof( dropped );
|
||||
++dropped[id];
|
||||
|
||||
cur += len;
|
||||
}
|
||||
}
|
||||
|
||||
int handle_message( const char *way,
|
||||
@@ -542,6 +700,10 @@ int handle_message( const char *way,
|
||||
packet cur;
|
||||
size_t id;
|
||||
|
||||
uint8_t delay_idx;
|
||||
char ** delay_list;
|
||||
uint8_t delay_list_len;
|
||||
|
||||
/* receive packet */
|
||||
if( ( ret = mbedtls_net_recv( src, cur.buf, sizeof( cur.buf ) ) ) <= 0 )
|
||||
{
|
||||
@@ -557,6 +719,37 @@ int handle_message( const char *way,
|
||||
|
||||
id = cur.len % sizeof( dropped );
|
||||
|
||||
if( strcmp( way, "S <- C" ) == 0 )
|
||||
{
|
||||
delay_list = opt.delay_cli;
|
||||
delay_list_len = opt.delay_cli_cnt;
|
||||
}
|
||||
else
|
||||
{
|
||||
delay_list = opt.delay_srv;
|
||||
delay_list_len = opt.delay_srv_cnt;
|
||||
}
|
||||
|
||||
/* Check if message type is in the list of messages
|
||||
* that should be delayed */
|
||||
for( delay_idx = 0; delay_idx < delay_list_len; delay_idx++ )
|
||||
{
|
||||
if( delay_list[ delay_idx ] == NULL )
|
||||
continue;
|
||||
|
||||
if( strcmp( delay_list[ delay_idx ], cur.type ) == 0 )
|
||||
{
|
||||
/* Delay message */
|
||||
delay_packet( &cur );
|
||||
|
||||
/* Remove entry from list */
|
||||
mbedtls_free( delay_list[delay_idx] );
|
||||
delay_list[delay_idx] = NULL;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/* do we want to drop, delay, or forward it? */
|
||||
if( ( opt.mtu != 0 &&
|
||||
cur.len > (unsigned) opt.mtu ) ||
|
||||
@@ -576,12 +769,11 @@ int handle_message( const char *way,
|
||||
strcmp( cur.type, "ApplicationData" ) != 0 &&
|
||||
! ( opt.protect_hvr &&
|
||||
strcmp( cur.type, "HelloVerifyRequest" ) == 0 ) &&
|
||||
prev.dst == NULL &&
|
||||
cur.len != (size_t) opt.protect_len &&
|
||||
dropped[id] < DROP_MAX &&
|
||||
rand() % opt.delay == 0 ) )
|
||||
{
|
||||
memcpy( &prev, &cur, sizeof( packet ) );
|
||||
delay_packet( &cur );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -589,14 +781,10 @@ int handle_message( const char *way,
|
||||
if( ( ret = send_packet( &cur, "forwarded" ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
/* send previously delayed message if any */
|
||||
if( prev.dst != NULL )
|
||||
{
|
||||
ret = send_packet( &prev, "delayed" );
|
||||
memset( &prev, 0, sizeof( packet ) );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
}
|
||||
/* send previously delayed messages if any */
|
||||
ret = send_delayed();
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
@@ -606,6 +794,7 @@ int main( int argc, char *argv[] )
|
||||
{
|
||||
int ret = 1;
|
||||
int exit_code = MBEDTLS_EXIT_FAILURE;
|
||||
uint8_t delay_idx;
|
||||
|
||||
mbedtls_net_context listen_fd, client_fd, server_fd;
|
||||
|
||||
@@ -800,6 +989,12 @@ exit:
|
||||
}
|
||||
#endif
|
||||
|
||||
for( delay_idx = 0; delay_idx < MAX_DELAYED_HS; delay_idx++ )
|
||||
{
|
||||
mbedtls_free( opt.delay_cli + delay_idx );
|
||||
mbedtls_free( opt.delay_srv + delay_idx );
|
||||
}
|
||||
|
||||
mbedtls_net_free( &client_fd );
|
||||
mbedtls_net_free( &server_fd );
|
||||
mbedtls_net_free( &listen_fd );
|
||||
@@ -809,7 +1004,7 @@ exit:
|
||||
fflush( stdout ); getchar();
|
||||
#endif
|
||||
|
||||
return( exit_code );
|
||||
mbedtls_exit( exit_code );
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_NET_C */
|
||||
|
@@ -1,6 +1,48 @@
|
||||
#!/bin/sh
|
||||
# -*-sh-basic-offset: 4-*-
|
||||
# Usage: udp_proxy_wrapper.sh [PROXY_PARAM...] -- [SERVER_PARAM...]
|
||||
#
|
||||
# Copyright The Mbed TLS Contributors
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
#
|
||||
# This file is provided under the Apache License 2.0, or the
|
||||
# GNU General Public License v2.0 or later.
|
||||
#
|
||||
# **********
|
||||
# Apache License 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.
|
||||
#
|
||||
# **********
|
||||
#
|
||||
# **********
|
||||
# GNU General Public License v2.0 or later:
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# **********
|
||||
|
||||
set -u
|
||||
|
||||
|
46
externals/mbedtls/programs/test/zeroize.c
vendored
46
externals/mbedtls/programs/test/zeroize.c
vendored
@@ -4,15 +4,36 @@
|
||||
* This is a simple test application used for debugger-driven testing to check
|
||||
* whether calls to mbedtls_platform_zeroize() are being eliminated by compiler
|
||||
* optimizations. This application is used by the GDB script at
|
||||
* tests/scripts/test_zeroize.gdb under the assumption that the code does not
|
||||
* change often (as opposed to the library code) because the script sets a
|
||||
* breakpoint at the last return statement in the main() function of this
|
||||
* program. The debugger facilities are then used to manually inspect the
|
||||
* memory and verify that the call to mbedtls_platform_zeroize() was not
|
||||
* eliminated.
|
||||
* tests/scripts/test_zeroize.gdb: the script sets a breakpoint at the last
|
||||
* return statement in the main() function of this program. The debugger
|
||||
* facilities are then used to manually inspect the memory and verify that the
|
||||
* call to mbedtls_platform_zeroize() was not eliminated.
|
||||
*
|
||||
* Copyright (C) 2018, Arm Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: GPL-2.0
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*
|
||||
* This file is provided under the Apache License 2.0, or the
|
||||
* GNU General Public License v2.0 or later.
|
||||
*
|
||||
* **********
|
||||
* Apache License 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.
|
||||
*
|
||||
* **********
|
||||
*
|
||||
* **********
|
||||
* GNU General Public License v2.0 or later:
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -28,7 +49,7 @@
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
||||
* **********
|
||||
*/
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
@@ -44,6 +65,7 @@
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#define mbedtls_printf printf
|
||||
#define mbedtls_exit exit
|
||||
#define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS
|
||||
#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE
|
||||
#endif
|
||||
@@ -74,14 +96,14 @@ int main( int argc, char** argv )
|
||||
{
|
||||
mbedtls_printf( "This program takes exactly 1 agument\n" );
|
||||
usage();
|
||||
return( exit_code );
|
||||
mbedtls_exit( exit_code );
|
||||
}
|
||||
|
||||
fp = fopen( argv[1], "r" );
|
||||
if( fp == NULL )
|
||||
{
|
||||
mbedtls_printf( "Could not open file '%s'\n", argv[1] );
|
||||
return( exit_code );
|
||||
mbedtls_exit( exit_code );
|
||||
}
|
||||
|
||||
while( ( c = fgetc( fp ) ) != EOF && p < end - 1 )
|
||||
@@ -99,5 +121,5 @@ int main( int argc, char** argv )
|
||||
fclose( fp );
|
||||
mbedtls_platform_zeroize( buf, sizeof( buf ) );
|
||||
|
||||
return( exit_code );
|
||||
mbedtls_exit( exit_code ); // GDB_BREAK_HERE -- don't remove this comment!
|
||||
}
|
||||
|
Reference in New Issue
Block a user