/* * Simple DTLS client program that does the same thing as echo-client but * over encrypted UDP link. * * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2017 Intel Corporation * 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. * */ #include #include #include #include #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 #define mbedtls_printf printf #define mbedtls_fprintf fprintf #endif #if !defined(MBEDTLS_SSL_CLI_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) || \ !defined(MBEDTLS_NET_C) || !defined(MBEDTLS_TIMING_C) || \ !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_CTR_DRBG_C) || \ !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_RSA_C) || \ !defined(MBEDTLS_CERTS_C) || !defined(MBEDTLS_PEM_PARSE_C) int main(void) { mbedtls_printf("MBEDTLS_SSL_CLI_C and/or MBEDTLS_SSL_PROTO_DTLS and/or " "MBEDTLS_NET_C and/or MBEDTLS_TIMING_C and/or " "MBEDTLS_ENTROPY_C and/or MBEDTLS_CTR_DRBG_C and/or " "MBEDTLS_X509_CRT_PARSE_C and/or MBEDTLS_RSA_C and/or " "MBEDTLS_CERTS_C and/or MBEDTLS_PEM_PARSE_C not defined.\n"); return(0); } #else #include #include "mbedtls/net_sockets.h" #include "mbedtls/debug.h" #include "mbedtls/ssl.h" #include "mbedtls/entropy.h" #include "mbedtls/ctr_drbg.h" #include "mbedtls/error.h" #include "mbedtls/certs.h" #include "mbedtls/timing.h" #define SERVER_PORT "4242" #define SERVER_NAME "localhost" #define HOSTNAME "localhost" #define SERVER_ADDR "127.0.0.1" /* forces IPv4 */ #define MESSAGE "Echo this" #define READ_TIMEOUT_MS 1000 #define MAX_RETRY 5 #define DEBUG_LEVEL 0 static bool debug; static int renegotiate = -1; #define ENTRY(e, expect_result) { sizeof(e), e, expect_result } #define ENTRY_OK(e) ENTRY(e, true) #define ENTRY_FAIL(e) ENTRY(e, false) static const unsigned char A[] = { 'A' }; static const unsigned char null_byte[] = { 0x00 }; static const unsigned char foobar[] = { 'f','o','o','b','a','r' }; static const unsigned char small_binary[] = { 0x20, 0xff, 0x00, 0x56 }; /* Generated by http://www.lipsum.com/ * 1202 bytes of Lorem Ipsum. * * This is the maximum we can send with encryption. */ static const char lorem_ipsum[] = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin congue orci et lectus ultricies, sed elementum urna finibus. Nam bibendum, massa id sollicitudin finibus, massa ante pharetra lacus, nec semper felis metus eu massa. Curabitur gravida, neque a pulvinar suscipit, felis massa maximus neque, eu sagittis felis enim nec justo. Suspendisse sit amet sem a magna aliquam tincidunt. Mauris consequat ante in consequat auctor. Nam eu congue mauris, congue aliquet metus. Etiam elit ipsum, vehicula et lectus at, dignissim accumsan turpis. Sed magna nisl, tempor ut dolor sed, feugiat pharetra velit. Nulla sed purus at elit dapibus lobortis. In hac habitasse platea dictumst. Praesent quis libero id enim aliquet viverra eleifend non urna. Vivamus metus justo, dignissim eget libero molestie, tincidunt pellentesque purus. Quisque pulvinar, nisi sed egestas vestibulum, ante felis elementum justo, ut viverra nisl est sagittis leo. Curabitur pharetra eros at felis ultricies efficitur." "\n" "Ut rutrum urna vitae neque rhoncus, id dictum ex dictum. Suspendisse venenatis vel mauris sed maximus. Sed malesuada elit vel neque hendrerit, in accumsan odio sodales. Aliquam erat volutpat. Praesent non situ.\n"; /* 256 bytes of binary data */ static const unsigned char array_256[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 0x00 }; /* 1280 bytes of binary data */ static const unsigned char array_1280[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 0x00 }; static struct data { int len; const unsigned char *buf; bool expecting_reply; } data[] = { ENTRY_OK(A), ENTRY_OK(foobar), ENTRY_OK(small_binary), ENTRY_OK("a bit longer data message"), ENTRY_OK(lorem_ipsum), ENTRY_OK(null_byte), ENTRY_OK(array_256), ENTRY_FAIL(array_1280), /* too long message will be discarded */ { 0, 0 } }; extern int optind, opterr, optopt; extern char *optarg; static void my_debug(void *ctx, int level, const char *file, int line, const char *str) { ((void) level); mbedtls_fprintf((FILE *) ctx, "%s:%04d: %s", file, line, str); fflush( (FILE *) ctx ); } int main(int argc, char *argv[]) { int ret, len, idx = 0; mbedtls_net_context server_fd; uint32_t flags; #define MAX_READ_BUF 2000 unsigned char buf[MAX_READ_BUF]; const char *pers = "dtls_client"; int retry_left = MAX_RETRY; bool forever = false; mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; mbedtls_ssl_context ssl; mbedtls_ssl_config conf; mbedtls_x509_crt cacert; mbedtls_timing_delay_context timer; int c; const char *target = SERVER_ADDR; const char *target_port = SERVER_PORT; #define CA_CERT_FILE "echo-apps-cert.pem" const char *ca_cert_file = CA_CERT_FILE; opterr = 0; while ((c = getopt(argc, argv, "ep:c:Dr")) != -1) { switch (c) { case 'e': forever = true; break; case 'c': ca_cert_file = optarg; break; case 'p': target_port = optarg; break; case 'r': /* Do a renegotiate once during the test run. */ srandom(time(0)); renegotiate = random() % 10; printf("Renegotating after %d messages.\n", renegotiate); break; case 'D': debug = true; break; } } if (optind < argc) target = argv[optind]; if (!target) { printf("usage: %s [-c ] [-p ] [-D] [-e]" "[-r] \n", argv[0]); printf("-c CA cert file (default is %s)\n", CA_CERT_FILE); printf("-p Port number to use (default is %s)\n", SERVER_PORT); printf("-r Renegoating keys once during the test run.\n"); printf("-e Run forever.\n"); printf("-D Activate debugging.\n"); exit(-EINVAL); } #if defined(MBEDTLS_DEBUG_C) mbedtls_debug_set_threshold(DEBUG_LEVEL); #endif /* * 0. Initialize the RNG and the session data */ mbedtls_net_init(&server_fd); mbedtls_ssl_init(&ssl); mbedtls_ssl_config_init(&conf); mbedtls_x509_crt_init(&cacert); mbedtls_ctr_drbg_init(&ctr_drbg); mbedtls_printf("\n . Seeding the random number generator..."); fflush(stdout); mbedtls_entropy_init(&entropy); if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) pers, strlen(pers))) != 0) { mbedtls_printf(" failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret); goto exit; } mbedtls_printf(" ok\n"); /* * 0. Load certificates */ mbedtls_printf(" . Loading the CA root certificate ..."); fflush(stdout); ret = mbedtls_x509_crt_parse_file(&cacert, ca_cert_file); if (ret < 0) { mbedtls_printf(" failed\n ! mbedtls_x509_crt_parse_file returned -0x%x\n\n", -ret); goto exit; } mbedtls_printf(" ok (%d skipped)\n", ret); /* * 1. Start the connection */ mbedtls_printf(" . Connecting to udp/%s/%s...", target, target_port); fflush(stdout); if ((ret = mbedtls_net_connect(&server_fd, target, target_port, MBEDTLS_NET_PROTO_UDP)) != 0) { mbedtls_printf(" failed\n ! mbedtls_net_connect returned %d\n\n", ret); goto exit; } mbedtls_printf(" ok\n"); /* * 2. Setup stuff */ mbedtls_printf(" . Setting up the DTLS structure..."); fflush(stdout); if ((ret = mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_DATAGRAM, MBEDTLS_SSL_PRESET_DEFAULT)) != 0) { mbedtls_printf(" failed\n ! mbedtls_ssl_config_defaults returned %d\n\n", ret); goto exit; } mbedtls_ssl_conf_cert_profile(&conf, &mbedtls_x509_crt_profile_default); mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_REQUIRED); mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL); mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg); mbedtls_ssl_conf_dbg(&conf, my_debug, stdout); if ((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0) { mbedtls_printf(" failed\n ! mbedtls_ssl_setup returned %d\n\n", ret); goto exit; } if ((ret = mbedtls_ssl_set_hostname(&ssl, HOSTNAME)) != 0) { mbedtls_printf(" failed\n ! mbedtls_ssl_set_hostname returned %d\n\n", ret); goto exit; } mbedtls_ssl_set_bio(&ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, mbedtls_net_recv_timeout); mbedtls_ssl_set_timer_cb(&ssl, &timer, mbedtls_timing_set_delay, mbedtls_timing_get_delay); mbedtls_printf(" ok\n"); /* * 4. Handshake */ mbedtls_printf(" . Performing the SSL/TLS handshake..."); fflush(stdout); do ret = mbedtls_ssl_handshake(&ssl); while(ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE); if (ret != 0) { mbedtls_printf(" failed\n ! mbedtls_ssl_handshake returned -0x%x\n\n", -ret); goto exit; } mbedtls_printf(" ok\n"); /* * 5. Verify the server certificate */ mbedtls_printf(" . Verifying peer X.509 certificate..."); /* In real life, we would have used MBEDTLS_SSL_VERIFY_REQUIRED so that the * handshake would not succeed if the peer's cert is bad. Even if we used * MBEDTLS_SSL_VERIFY_OPTIONAL, we would bail out here if ret != 0 */ if ((flags = mbedtls_ssl_get_verify_result(&ssl)) != 0) { char vrfy_buf[512]; mbedtls_printf(" failed\n"); mbedtls_x509_crt_verify_info(vrfy_buf, sizeof(vrfy_buf), " ! ", flags); mbedtls_printf("%s\n", vrfy_buf); goto exit; } else mbedtls_printf(" ok\n"); /* * 6. Write the echo request */ send_request: mbedtls_printf(" > Write to server:"); fflush(stdout); len = data[idx].len; /* For time being, restrict largest frame to 1024 bytes so that we make * sure that the sent packets are not fragmented. */ if (len > 1024) len = 1024; if (len == 0) { mbedtls_printf(" Invalid byte count 0 in the data array " "at index %d\n", idx); goto close_notify; } do ret = mbedtls_ssl_write(&ssl, data[idx].buf, len); while(ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE); if (ret < 0) { mbedtls_printf(" failed\n ! mbedtls_ssl_write returned %d\n\n", ret); goto exit; } mbedtls_printf(" %d bytes written\n", ret); /* * 7. Read the echo response */ mbedtls_printf(" < Read from server:"); fflush(stdout); memset(buf, 0, sizeof(buf)); do ret = mbedtls_ssl_read(&ssl, buf, len); while(ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE); if (ret <= 0) { switch(ret) { case MBEDTLS_ERR_SSL_TIMEOUT: mbedtls_printf(" timeout\n\n"); if (retry_left-- > 0) goto send_request; goto exit; case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: mbedtls_printf(" connection was closed gracefully\n"); ret = 0; goto close_notify; default: mbedtls_printf(" mbedtls_ssl_read returned -0x%x\n\n", -ret); goto exit; } } mbedtls_printf(" %d bytes read\n", ret); if (ret != len) { mbedtls_printf(" Sent and received byte count mismatch " "(%d vs %d)\n", len, ret); goto close_notify; } if (memcmp(data[idx].buf, buf, len)) { mbedtls_printf(" Sent and received data mismatch\n"); goto close_notify; } idx++; if (idx >= ((sizeof(data) / sizeof(data[0])) - 1)) { if (!forever) { goto close_notify; } idx = 0; } goto send_request; /* * 8. Done, cleanly close the connection */ close_notify: mbedtls_printf(" . Closing the connection..."); /* No error checking, the connection might be closed already */ do ret = mbedtls_ssl_close_notify(&ssl); while(ret == MBEDTLS_ERR_SSL_WANT_WRITE); ret = 0; mbedtls_printf(" done\n"); /* * 9. Final clean-ups and exit */ exit: #ifdef MBEDTLS_ERROR_C if (ret != 0) { char error_buf[100]; mbedtls_strerror(ret, error_buf, 100); mbedtls_printf("Last error was: %d - %s\n\n", ret, error_buf); } #endif mbedtls_net_free(&server_fd); mbedtls_x509_crt_free(&cacert); mbedtls_ssl_free(&ssl); mbedtls_ssl_config_free(&conf); mbedtls_ctr_drbg_free(&ctr_drbg); mbedtls_entropy_free(&entropy); #if defined(_WIN32) mbedtls_printf(" + Press Enter to exit this program.\n"); fflush(stdout); getchar(); #endif /* Shell can not handle large exit numbers -> 1 for errors */ if (ret < 0) ret = 1; return(ret); } #endif /* MBEDTLS_SSL_CLI_C && MBEDTLS_SSL_PROTO_DTLS && MBEDTLS_NET_C && MBEDTLD_TIMING_C && MBEDTLS_ENTROPY_C && MBEDTLS_CTR_DRBG_C && MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_RSA_C && MBEDTLS_CERTS_C && MBEDTLS_PEM_PARSE_C */