1 /*
2  *  Simple DTLS client program that does the same thing as echo-client but
3  *  over encrypted UDP link.
4  *
5  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
6  *  Copyright (C) 2017 Intel Corporation
7  *  SPDX-License-Identifier: Apache-2.0
8  *
9  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
10  *  not use this file except in compliance with the License.
11  *  You may obtain a copy of the License at
12  *
13  *  http://www.apache.org/licenses/LICENSE-2.0
14  *
15  *  Unless required by applicable law or agreed to in writing, software
16  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
17  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  *  See the License for the specific language governing permissions and
19  *  limitations under the License.
20  *
21  */
22 
23 #include <errno.h>
24 #include <stdbool.h>
25 #include <stdint.h>
26 #include <unistd.h>
27 
28 #if !defined(MBEDTLS_CONFIG_FILE)
29 #include "mbedtls/config.h"
30 #else
31 #include MBEDTLS_CONFIG_FILE
32 #endif
33 
34 #if defined(MBEDTLS_PLATFORM_C)
35 #include "mbedtls/platform.h"
36 #else
37 #include <stdio.h>
38 #define mbedtls_printf     printf
39 #define mbedtls_fprintf    fprintf
40 #endif
41 
42 #if !defined(MBEDTLS_SSL_CLI_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) ||    \
43     !defined(MBEDTLS_NET_C)  || !defined(MBEDTLS_TIMING_C) ||             \
44     !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_CTR_DRBG_C) ||        \
45     !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_RSA_C) ||      \
46     !defined(MBEDTLS_CERTS_C) || !defined(MBEDTLS_PEM_PARSE_C)
main(void)47 int main(void)
48 {
49     mbedtls_printf("MBEDTLS_SSL_CLI_C and/or MBEDTLS_SSL_PROTO_DTLS and/or "
50             "MBEDTLS_NET_C and/or MBEDTLS_TIMING_C and/or "
51             "MBEDTLS_ENTROPY_C and/or MBEDTLS_CTR_DRBG_C and/or "
52             "MBEDTLS_X509_CRT_PARSE_C and/or MBEDTLS_RSA_C and/or "
53             "MBEDTLS_CERTS_C and/or MBEDTLS_PEM_PARSE_C not defined.\n");
54     return(0);
55 }
56 #else
57 
58 #include <string.h>
59 
60 #include "mbedtls/net_sockets.h"
61 #include "mbedtls/debug.h"
62 #include "mbedtls/ssl.h"
63 #include "mbedtls/entropy.h"
64 #include "mbedtls/ctr_drbg.h"
65 #include "mbedtls/error.h"
66 #include "mbedtls/certs.h"
67 #include "mbedtls/timing.h"
68 
69 #define SERVER_PORT "4242"
70 #define SERVER_NAME "localhost"
71 #define HOSTNAME "localhost"
72 #define SERVER_ADDR "127.0.0.1" /* forces IPv4 */
73 #define MESSAGE     "Echo this"
74 
75 #define READ_TIMEOUT_MS 1000
76 #define MAX_RETRY       5
77 
78 #define DEBUG_LEVEL 0
79 
80 static bool debug;
81 static int renegotiate = -1;
82 
83 #define ENTRY(e, expect_result) { sizeof(e), e, expect_result }
84 #define ENTRY_OK(e) ENTRY(e, true)
85 #define ENTRY_FAIL(e) ENTRY(e, false)
86 
87 static const unsigned char A[] = { 'A' };
88 static const unsigned char null_byte[] = { 0x00 };
89 static const unsigned char foobar[] = { 'f','o','o','b','a','r' };
90 static const unsigned char small_binary[] = { 0x20, 0xff, 0x00, 0x56 };
91 
92 /* Generated by http://www.lipsum.com/
93  * 1202 bytes of Lorem Ipsum.
94  *
95  * This is the maximum we can send with encryption.
96  */
97 static const char lorem_ipsum[] =
98 	"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."
99 	"\n"
100 	"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";
101 
102 /* 256 bytes of binary data */
103 static const unsigned char array_256[] = {
104 	0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
105 	0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
106 	0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
107 	0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
108 	0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
109 	0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
110 	0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
111 	0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40,
112 	0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
113 	0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
114 	0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
115 	0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60,
116 	0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
117 	0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
118 	0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
119 	0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80,
120 	0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
121 	0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
122 	0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
123 	0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0,
124 	0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8,
125 	0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0,
126 	0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
127 	0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0,
128 	0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8,
129 	0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0,
130 	0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
131 	0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0,
132 	0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8,
133 	0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0,
134 	0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
135 	0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 0x00
136 };
137 
138 /* 1280 bytes of binary data */
139 static const unsigned char array_1280[] = {
140 	0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
141 	0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
142 	0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
143 	0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
144 	0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
145 	0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
146 	0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
147 	0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40,
148 	0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
149 	0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
150 	0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
151 	0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60,
152 	0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
153 	0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
154 	0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
155 	0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80,
156 	0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
157 	0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
158 	0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
159 	0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0,
160 	0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8,
161 	0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0,
162 	0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
163 	0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0,
164 	0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8,
165 	0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0,
166 	0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
167 	0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0,
168 	0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8,
169 	0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0,
170 	0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
171 	0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 0x00,
172 	0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
173 	0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
174 	0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
175 	0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
176 	0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
177 	0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
178 	0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
179 	0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40,
180 	0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
181 	0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
182 	0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
183 	0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60,
184 	0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
185 	0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
186 	0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
187 	0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80,
188 	0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
189 	0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
190 	0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
191 	0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0,
192 	0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8,
193 	0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0,
194 	0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
195 	0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0,
196 	0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8,
197 	0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0,
198 	0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
199 	0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0,
200 	0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8,
201 	0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0,
202 	0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
203 	0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 0x00,
204 	0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
205 	0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
206 	0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
207 	0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
208 	0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
209 	0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
210 	0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
211 	0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40,
212 	0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
213 	0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
214 	0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
215 	0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60,
216 	0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
217 	0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
218 	0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
219 	0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80,
220 	0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
221 	0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
222 	0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
223 	0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0,
224 	0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8,
225 	0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0,
226 	0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
227 	0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0,
228 	0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8,
229 	0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0,
230 	0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
231 	0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0,
232 	0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8,
233 	0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0,
234 	0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
235 	0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 0x00,
236 	0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
237 	0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
238 	0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
239 	0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
240 	0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
241 	0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
242 	0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
243 	0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40,
244 	0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
245 	0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
246 	0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
247 	0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60,
248 	0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
249 	0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
250 	0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
251 	0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80,
252 	0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
253 	0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
254 	0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
255 	0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0,
256 	0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8,
257 	0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0,
258 	0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
259 	0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0,
260 	0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8,
261 	0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0,
262 	0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
263 	0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0,
264 	0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8,
265 	0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0,
266 	0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
267 	0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 0x00,
268 	0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
269 	0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
270 	0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
271 	0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
272 	0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
273 	0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
274 	0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
275 	0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40,
276 	0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
277 	0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
278 	0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
279 	0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60,
280 	0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
281 	0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
282 	0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
283 	0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80,
284 	0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
285 	0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
286 	0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
287 	0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0,
288 	0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8,
289 	0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0,
290 	0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
291 	0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0,
292 	0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8,
293 	0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0,
294 	0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
295 	0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0,
296 	0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8,
297 	0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0,
298 	0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
299 	0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 0x00
300 };
301 
302 static struct data {
303 	int len;
304 	const unsigned char *buf;
305 	bool expecting_reply;
306 } data[] = {
307 	ENTRY_OK(A),
308 	ENTRY_OK(foobar),
309 	ENTRY_OK(small_binary),
310 	ENTRY_OK("a bit longer data message"),
311 	ENTRY_OK(lorem_ipsum),
312 	ENTRY_OK(null_byte),
313 	ENTRY_OK(array_256),
314 	ENTRY_FAIL(array_1280), /* too long message will be discarded */
315 
316 	{ 0, 0 }
317 };
318 
319 extern int optind, opterr, optopt;
320 extern char *optarg;
321 
my_debug(void * ctx,int level,const char * file,int line,const char * str)322 static void my_debug(void *ctx, int level,
323                       const char *file, int line,
324                       const char *str)
325 {
326 	((void) level);
327 
328 	mbedtls_fprintf((FILE *) ctx, "%s:%04d: %s", file, line, str);
329 	fflush( (FILE *) ctx );
330 }
331 
main(int argc,char * argv[])332 int main(int argc, char *argv[])
333 {
334 	int ret, len, idx = 0;
335 	mbedtls_net_context server_fd;
336 	uint32_t flags;
337 #define MAX_READ_BUF 2000
338 	unsigned char buf[MAX_READ_BUF];
339 	const char *pers = "dtls_client";
340 	int retry_left = MAX_RETRY;
341 	bool forever = false;
342 
343 	mbedtls_entropy_context entropy;
344 	mbedtls_ctr_drbg_context ctr_drbg;
345 	mbedtls_ssl_context ssl;
346 	mbedtls_ssl_config conf;
347 	mbedtls_x509_crt cacert;
348 	mbedtls_timing_delay_context timer;
349 
350 	int c;
351 	const char *target = SERVER_ADDR;
352 	const char *target_port = SERVER_PORT;
353 
354 #define CA_CERT_FILE "echo-apps-cert.pem"
355 	const char *ca_cert_file = CA_CERT_FILE;
356 
357 	opterr = 0;
358 
359 	while ((c = getopt(argc, argv, "ep:c:Dr")) != -1) {
360 		switch (c) {
361 		case 'e':
362 			forever = true;
363 			break;
364 		case 'c':
365 			ca_cert_file = optarg;
366 			break;
367 		case 'p':
368 			target_port = optarg;
369 			break;
370 		case 'r':
371 			/* Do a renegotiate once during the test run. */
372 			srandom(time(0));
373 			renegotiate = random() % 10;
374 			printf("Renegotating after %d messages.\n", renegotiate);
375 			break;
376 		case 'D':
377 			debug = true;
378 			break;
379 		}
380 	}
381 
382 	if (optind < argc)
383 		target = argv[optind];
384 
385 	if (!target) {
386 		printf("usage: %s [-c <CA cert file>] [-p <port>] [-D] [-e]"
387 		       "[-r] <IPv{6|4} address of the dtls-server>\n", argv[0]);
388 		printf("-c CA cert file (default is %s)\n", CA_CERT_FILE);
389 		printf("-p Port number to use (default is %s)\n", SERVER_PORT);
390 		printf("-r Renegoating keys once during the test run.\n");
391 		printf("-e Run forever.\n");
392 		printf("-D Activate debugging.\n");
393 		exit(-EINVAL);
394 	}
395 
396 #if defined(MBEDTLS_DEBUG_C)
397 	mbedtls_debug_set_threshold(DEBUG_LEVEL);
398 #endif
399 
400 	/*
401 	 * 0. Initialize the RNG and the session data
402 	 */
403 	mbedtls_net_init(&server_fd);
404 	mbedtls_ssl_init(&ssl);
405 	mbedtls_ssl_config_init(&conf);
406 	mbedtls_x509_crt_init(&cacert);
407 	mbedtls_ctr_drbg_init(&ctr_drbg);
408 
409 	mbedtls_printf("\n  . Seeding the random number generator...");
410 	fflush(stdout);
411 
412 	mbedtls_entropy_init(&entropy);
413 	if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func,
414 					 &entropy,
415 					 (const unsigned char *) pers,
416 					 strlen(pers))) != 0) {
417 		mbedtls_printf(" failed\n  ! mbedtls_ctr_drbg_seed returned %d\n", ret);
418 		goto exit;
419 	}
420 
421 	mbedtls_printf(" ok\n");
422 
423 	/*
424 	 * 0. Load certificates
425 	 */
426 	mbedtls_printf("  . Loading the CA root certificate ...");
427 	fflush(stdout);
428 
429 	ret = mbedtls_x509_crt_parse_file(&cacert, ca_cert_file);
430 	if (ret < 0) {
431 		mbedtls_printf(" failed\n  !  mbedtls_x509_crt_parse_file returned -0x%x\n\n", -ret);
432 		goto exit;
433 	}
434 
435 	mbedtls_printf(" ok (%d skipped)\n", ret);
436 
437 	/*
438 	 * 1. Start the connection
439 	 */
440 	mbedtls_printf("  . Connecting to udp/%s/%s...", target, target_port);
441 	fflush(stdout);
442 
443 	if ((ret = mbedtls_net_connect(&server_fd, target,
444 				       target_port,
445 				       MBEDTLS_NET_PROTO_UDP)) != 0) {
446 		mbedtls_printf(" failed\n  ! mbedtls_net_connect returned %d\n\n", ret);
447 		goto exit;
448 	}
449 
450 	mbedtls_printf(" ok\n");
451 
452 	/*
453 	 * 2. Setup stuff
454 	 */
455 	mbedtls_printf("  . Setting up the DTLS structure...");
456 	fflush(stdout);
457 
458 	if ((ret = mbedtls_ssl_config_defaults(&conf,
459 					       MBEDTLS_SSL_IS_CLIENT,
460 					       MBEDTLS_SSL_TRANSPORT_DATAGRAM,
461 					       MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
462 		mbedtls_printf(" failed\n  ! mbedtls_ssl_config_defaults returned %d\n\n", ret);
463 		goto exit;
464 	}
465 
466 	mbedtls_ssl_conf_cert_profile(&conf, &mbedtls_x509_crt_profile_default);
467 	mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_REQUIRED);
468 	mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL);
469 	mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg);
470 	mbedtls_ssl_conf_dbg(&conf, my_debug, stdout);
471 
472 	if ((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0) {
473 		mbedtls_printf(" failed\n  ! mbedtls_ssl_setup returned %d\n\n", ret);
474 		goto exit;
475 	}
476 
477 	if ((ret = mbedtls_ssl_set_hostname(&ssl, HOSTNAME)) != 0) {
478 		mbedtls_printf(" failed\n  ! mbedtls_ssl_set_hostname returned %d\n\n", ret);
479 		goto exit;
480 	}
481 
482 	mbedtls_ssl_set_bio(&ssl, &server_fd,
483 			    mbedtls_net_send, mbedtls_net_recv,
484 			    mbedtls_net_recv_timeout);
485 
486 	mbedtls_ssl_set_timer_cb(&ssl, &timer, mbedtls_timing_set_delay,
487 				 mbedtls_timing_get_delay);
488 
489 	mbedtls_printf(" ok\n");
490 
491 	/*
492 	 * 4. Handshake
493 	 */
494 	mbedtls_printf("  . Performing the SSL/TLS handshake...");
495 	fflush(stdout);
496 
497 	do ret = mbedtls_ssl_handshake(&ssl);
498 	while(ret == MBEDTLS_ERR_SSL_WANT_READ ||
499 	      ret == MBEDTLS_ERR_SSL_WANT_WRITE);
500 
501 	if (ret != 0) {
502 		mbedtls_printf(" failed\n  ! mbedtls_ssl_handshake returned -0x%x\n\n", -ret);
503 		goto exit;
504 	}
505 
506 	mbedtls_printf(" ok\n");
507 
508 	/*
509 	 * 5. Verify the server certificate
510 	 */
511 	mbedtls_printf("  . Verifying peer X.509 certificate...");
512 
513 	/* In real life, we would have used MBEDTLS_SSL_VERIFY_REQUIRED so that the
514 	 * handshake would not succeed if the peer's cert is bad.  Even if we used
515 	 * MBEDTLS_SSL_VERIFY_OPTIONAL, we would bail out here if ret != 0 */
516 	if ((flags = mbedtls_ssl_get_verify_result(&ssl)) != 0) {
517 		char vrfy_buf[512];
518 
519 		mbedtls_printf(" failed\n");
520 
521 		mbedtls_x509_crt_verify_info(vrfy_buf, sizeof(vrfy_buf), "  ! ", flags);
522 
523 		mbedtls_printf("%s\n", vrfy_buf);
524 
525 		goto exit;
526 	} else
527 		mbedtls_printf(" ok\n");
528 
529 	/*
530 	 * 6. Write the echo request
531 	 */
532 send_request:
533 	mbedtls_printf("  > Write to server:");
534 	fflush(stdout);
535 
536 	len = data[idx].len;
537 
538 	/* For time being, restrict largest frame to 1024 bytes so that we make
539 	 * sure that the sent packets are not fragmented.
540 	 */
541 	if (len > 1024)
542 		len = 1024;
543 
544 	if (len == 0) {
545 		mbedtls_printf(" Invalid byte count 0 in the data array "
546 			       "at index %d\n", idx);
547 		goto close_notify;
548 	}
549 
550 	do ret = mbedtls_ssl_write(&ssl, data[idx].buf, len);
551 	while(ret == MBEDTLS_ERR_SSL_WANT_READ ||
552 	      ret == MBEDTLS_ERR_SSL_WANT_WRITE);
553 
554 	if (ret < 0) {
555 		mbedtls_printf(" failed\n  ! mbedtls_ssl_write returned %d\n\n", ret);
556 		goto exit;
557 	}
558 
559 	mbedtls_printf(" %d bytes written\n", ret);
560 
561 	/*
562 	 * 7. Read the echo response
563 	 */
564 	mbedtls_printf("  < Read from server:");
565 	fflush(stdout);
566 
567 	memset(buf, 0, sizeof(buf));
568 
569 	do ret = mbedtls_ssl_read(&ssl, buf, len);
570 	while(ret == MBEDTLS_ERR_SSL_WANT_READ ||
571 	      ret == MBEDTLS_ERR_SSL_WANT_WRITE);
572 
573 	if (ret <= 0) {
574 		switch(ret) {
575 		case MBEDTLS_ERR_SSL_TIMEOUT:
576 			mbedtls_printf(" timeout\n\n");
577 			if (retry_left-- > 0)
578 				goto send_request;
579 			goto exit;
580 
581 		case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY:
582 			mbedtls_printf(" connection was closed gracefully\n");
583 			ret = 0;
584 			goto close_notify;
585 
586 		default:
587 			mbedtls_printf(" mbedtls_ssl_read returned -0x%x\n\n", -ret);
588 			goto exit;
589 		}
590 	}
591 
592 	mbedtls_printf(" %d bytes read\n", ret);
593 
594 	if (ret != len) {
595 		mbedtls_printf(" Sent and received byte count mismatch "
596 			       "(%d vs %d)\n", len, ret);
597 		goto close_notify;
598 	}
599 
600 	if (memcmp(data[idx].buf, buf, len)) {
601 		mbedtls_printf(" Sent and received data mismatch\n");
602 		goto close_notify;
603 	}
604 
605 	idx++;
606 
607 	if (idx >= ((sizeof(data) / sizeof(data[0])) - 1)) {
608 		if (!forever) {
609 			goto close_notify;
610 		}
611 
612 		idx = 0;
613 	}
614 
615 	goto send_request;
616 
617 	/*
618 	 * 8. Done, cleanly close the connection
619 	 */
620 close_notify:
621 	mbedtls_printf("  . Closing the connection...");
622 
623 	/* No error checking, the connection might be closed already */
624 	do ret = mbedtls_ssl_close_notify(&ssl);
625 	while(ret == MBEDTLS_ERR_SSL_WANT_WRITE);
626 	ret = 0;
627 
628 	mbedtls_printf(" done\n");
629 
630 	/*
631 	 * 9. Final clean-ups and exit
632 	 */
633 exit:
634 
635 #ifdef MBEDTLS_ERROR_C
636 	if (ret != 0) {
637 		char error_buf[100];
638 		mbedtls_strerror(ret, error_buf, 100);
639 		mbedtls_printf("Last error was: %d - %s\n\n", ret, error_buf);
640 	}
641 #endif
642 
643 	mbedtls_net_free(&server_fd);
644 
645 	mbedtls_x509_crt_free(&cacert);
646 	mbedtls_ssl_free(&ssl);
647 	mbedtls_ssl_config_free(&conf);
648 	mbedtls_ctr_drbg_free(&ctr_drbg);
649 	mbedtls_entropy_free(&entropy);
650 
651 #if defined(_WIN32)
652 	mbedtls_printf("  + Press Enter to exit this program.\n");
653 	fflush(stdout); getchar();
654 #endif
655 
656 	/* Shell can not handle large exit numbers -> 1 for errors */
657 	if (ret < 0)
658 		ret = 1;
659 
660 	return(ret);
661 }
662 #endif /* MBEDTLS_SSL_CLI_C && MBEDTLS_SSL_PROTO_DTLS && MBEDTLS_NET_C &&
663           MBEDTLD_TIMING_C && MBEDTLS_ENTROPY_C && MBEDTLS_CTR_DRBG_C &&
664           MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_RSA_C && MBEDTLS_CERTS_C &&
665           MBEDTLS_PEM_PARSE_C */
666