blob: 09116b952cb92cacdd3b325ef4ddbbb4c003f7a2 [file] [log] [blame]
Piotr Nowicki9370f902020-03-13 14:43:22 +01001/*
2 * MbedTLS SSL context deserializer from base64 code
3 *
4 * Copyright (C) 2006-2020, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * This file is part of mbed TLS (https://tls.mbed.org)
20 */
21
Piotr Nowicki88ebbbf2020-03-13 16:26:08 +010022#include <stdio.h>
23#include <stdlib.h>
Piotr Nowicki14d31052020-03-16 14:05:22 +010024#include <stdint.h>
Piotr Nowicki88ebbbf2020-03-13 16:26:08 +010025#include <stdarg.h>
26#include <string.h>
Piotr Nowickic7d681c2020-03-17 09:51:31 +010027#include "mbedtls/error.h"
28#include "mbedtls/base64.h"
Piotr Nowicki4e192002020-03-18 17:27:29 +010029#include "mbedtls/md.h"
Piotr Nowicki88ebbbf2020-03-13 16:26:08 +010030
31/*
32 * This program version
33 */
34#define PROG_NAME "ssl_base64_dump"
35#define VER_MAJOR 0
36#define VER_MINOR 1
37
38/*
Piotr Nowicki6b2baf92020-03-17 15:36:52 +010039 * Flags copied from the mbedTLS library.
40 */
41#define SESSION_CONFIG_TIME_BIT ( 1 << 0 )
42#define SESSION_CONFIG_CRT_BIT ( 1 << 1 )
43#define SESSION_CONFIG_CLIENT_TICKET_BIT ( 1 << 2 )
44#define SESSION_CONFIG_MFL_BIT ( 1 << 3 )
45#define SESSION_CONFIG_TRUNC_HMAC_BIT ( 1 << 4 )
46#define SESSION_CONFIG_ETM_BIT ( 1 << 5 )
47#define SESSION_CONFIG_TICKET_BIT ( 1 << 6 )
48
49#define CONTEXT_CONFIG_DTLS_CONNECTION_ID_BIT ( 1 << 0 )
50#define CONTEXT_CONFIG_DTLS_BADMAC_LIMIT_BIT ( 1 << 1 )
51#define CONTEXT_CONFIG_DTLS_ANTI_REPLAY_BIT ( 1 << 2 )
52#define CONTEXT_CONFIG_ALPN_BIT ( 1 << 3 )
53
Piotr Nowickiab3ecd82020-03-18 15:12:41 +010054#define TRANSFORM_RANDBYTE_LEN 64
55
Piotr Nowicki6b2baf92020-03-17 15:36:52 +010056/*
Piotr Nowicki88ebbbf2020-03-13 16:26:08 +010057 * Global values
58 */
59FILE *b64_file = NULL; /* file with base64 codes to deserialize */
60char debug = 0; /* flag for debug messages */
61
62/*
63 * Basic printing functions
64 */
65void print_version( )
66{
67 printf( "%s v%d.%d\n", PROG_NAME, VER_MAJOR, VER_MINOR );
68}
69
70void print_usage( )
71{
72 print_version();
73 printf(
74 "Usage:\n"
75 "\t-f path - Path to the file with base64 code\n"
76 "\t-v - Show version\n"
77 "\t-h - Show this usage\n"
78 "\t-d - Print more information\n"
79 "\n"
80 );
81}
82
83void printf_dbg( const char *str, ... )
84{
85 if( debug )
86 {
87 va_list args;
88 va_start( args, str );
89 printf( "debug: " );
90 vprintf( str, args );
91 fflush( stdout );
92 va_end( args );
93 }
94}
95
96void printf_err( const char *str, ... )
97{
98 va_list args;
99 va_start( args, str );
100 fprintf( stderr, "ERROR: " );
101 vfprintf( stderr, str, args );
102 fflush( stderr );
103 va_end( args );
104}
105
106/*
107 * Exit from the program in case of error
108 */
109void error_exit()
110{
111 if( NULL != b64_file )
112 {
113 fclose( b64_file );
114 }
115 exit( -1 );
116}
117
118/*
119 * This function takes the input arguments of this program
120 */
121void parse_arguments( int argc, char *argv[] )
122{
123 int i = 1;
124
125 if( argc < 2 )
126 {
127 print_usage();
128 error_exit();
129 }
130
131 while( i < argc )
132 {
133 if( strcmp( argv[i], "-d" ) == 0 )
134 {
135 debug = 1;
136 }
137 else if( strcmp( argv[i], "-h" ) == 0 )
138 {
139 print_usage();
140 }
141 else if( strcmp( argv[i], "-v" ) == 0 )
142 {
143 print_version();
144 }
145 else if( strcmp( argv[i], "-f" ) == 0 )
146 {
147 if( ++i >= argc )
148 {
149 printf_err( "File path is empty\n" );
150 error_exit();
151 }
152
153 if( ( b64_file = fopen( argv[i], "r" ) ) == NULL )
154 {
155 printf_err( "Cannot find file \"%s\"\n", argv[i] );
156 error_exit();
157 }
158 }
159 else
160 {
161 print_usage();
162 error_exit();
163 }
164
165 i++;
166 }
167}
168
Piotr Nowicki14d31052020-03-16 14:05:22 +0100169/*
Piotr Nowicki6842c9b2020-03-16 17:52:56 +0100170 * This function prints base64 code to the stdout
171 */
Piotr Nowickiab3ecd82020-03-18 15:12:41 +0100172void print_b64( const uint8_t *b, size_t len )
Piotr Nowicki6842c9b2020-03-16 17:52:56 +0100173{
174 size_t i = 0;
Piotr Nowickiab3ecd82020-03-18 15:12:41 +0100175 const uint8_t *end = b + len;
Piotr Nowickic7d681c2020-03-17 09:51:31 +0100176 printf("\t");
Piotr Nowicki6842c9b2020-03-16 17:52:56 +0100177 while( b < end )
178 {
Piotr Nowickic7d681c2020-03-17 09:51:31 +0100179 if( ++i > 75 )
Piotr Nowicki6842c9b2020-03-16 17:52:56 +0100180 {
Piotr Nowickic7d681c2020-03-17 09:51:31 +0100181 printf( "\n\t" );
Piotr Nowicki6842c9b2020-03-16 17:52:56 +0100182 i = 0;
183 }
184 printf( "%c", *b++ );
185 }
186 printf( "\n" );
187 fflush( stdout );
188}
189
190/*
Piotr Nowickic7d681c2020-03-17 09:51:31 +0100191 * This function prints hex code from the buffer to the stdout.
192 */
Piotr Nowickiab3ecd82020-03-18 15:12:41 +0100193void print_hex( const uint8_t *b, size_t len )
Piotr Nowickic7d681c2020-03-17 09:51:31 +0100194{
195 size_t i = 0;
Piotr Nowickiab3ecd82020-03-18 15:12:41 +0100196 const uint8_t *end = b + len;
Piotr Nowickic7d681c2020-03-17 09:51:31 +0100197 printf("\t");
198 while( b < end )
199 {
Piotr Nowickiab3ecd82020-03-18 15:12:41 +0100200 printf( "%02X ", (uint8_t) *b++ );
Piotr Nowickic7d681c2020-03-17 09:51:31 +0100201 if( ++i > 25 )
202 {
203 printf("\n\t");
204 i = 0;
205 }
206 }
207 printf("\n");
208 fflush(stdout);
209}
210
211/*
Piotr Nowicki6b2baf92020-03-17 15:36:52 +0100212 * Print the input string if the bit is set in the value
213 */
214void print_if_bit( const char *str, int bit, int val )
215{
216 if( bit & val )
217 {
218 printf( "\t%s\n", str );
219 }
220}
221
222/*
Piotr Nowicki14d31052020-03-16 14:05:22 +0100223 * Read next base64 code from the 'b64_file'. The 'b64_file' must be opened
224 * previously. After each call to this function, the internal file position
225 * indicator of the global b64_file is advanced.
226 *
227 * /p b64 buffer for input data
228 * /p max_len the maximum number of bytes to write
229 *
230 * \retval number of bytes written in to the b64 buffer or 0 in case no more
231 * data was found
232 */
Piotr Nowickiab3ecd82020-03-18 15:12:41 +0100233size_t read_next_b64_code( uint8_t *b64, size_t max_len )
Piotr Nowicki14d31052020-03-16 14:05:22 +0100234{
235 size_t len = 0;
236 uint32_t missed = 0;
237 char pad = 0;
238 char c = 0;
239
240 while( EOF != c )
241 {
242 char c_valid = 0;
243
244 c = (char) fgetc( b64_file );
245
246 if( pad == 1 )
247 {
248 if( c == '=' )
249 {
250 c_valid = 1;
251 pad = 2;
252 }
253 }
254 else if( ( c >= 'A' && c <= 'Z' ) ||
255 ( c >= 'a' && c <= 'z' ) ||
256 ( c >= '0' && c <= '9' ) ||
257 c == '+' || c == '/' )
258 {
259 c_valid = 1;
260 }
261 else if( c == '=' )
262 {
263 c_valid = 1;
264 pad = 1;
265 }
266 else if( c == '-' )
267 {
268 c = '+';
269 c_valid = 1;
270 }
271 else if( c == '_' )
272 {
273 c = '/';
274 c_valid = 1;
275 }
276
277 if( c_valid )
278 {
279 if( len < max_len )
280 {
281 b64[ len++ ] = c;
282 }
283 else
284 {
285 missed++;
286 }
287 }
288 else if( len > 0 )
289 {
290 if( missed > 0 )
291 {
292 printf_err( "Buffer for the base64 code is too small. Missed %u characters\n", missed );
293 }
294 return len;
295 }
296 }
297
298 printf_dbg( "End of file\n" );
299 return 0;
300}
301
Piotr Nowicki6b2baf92020-03-17 15:36:52 +0100302/*
303 * This function deserializes and prints to the stdout all obtained information
Piotr Nowickiab3ecd82020-03-18 15:12:41 +0100304 * about the session from provided data. This function was built based on
305 * mbedtls_ssl_session_load(). mbedtls_ssl_session_load() could not be used
306 * due to dependencies on the mbedTLS configuration.
307 *
308 * The data structure in the buffer:
309 * uint64 start_time;
310 * uint8 ciphersuite[2]; // defined by the standard
311 * uint8 compression; // 0 or 1
312 * uint8 session_id_len; // at most 32
313 * opaque session_id[32];
314 * opaque master[48]; // fixed length in the standard
315 * uint32 verify_result;
316 * opaque peer_cert<0..2^24-1>; // length 0 means no peer cert
317 * opaque ticket<0..2^24-1>; // length 0 means no ticket
318 * uint32 ticket_lifetime;
319 * uint8 mfl_code; // up to 255 according to standard
320 * uint8 trunc_hmac; // 0 or 1
321 * uint8 encrypt_then_mac; // 0 or 1
322 *
323 * /p ssl pointer to serialized session
324 * /p len number of bytes in the buffer
325 * /p session_cfg_flag session configuration flags
326 */
327void print_deserialized_ssl_session( const uint8_t *ssl, uint32_t len,
328 int session_cfg_flag )
329{
Piotr Nowicki4e192002020-03-18 17:27:29 +0100330 mbedtls_md_type_t peer_cert_digest_type;
331 uint32_t peer_cert_digest_len, cert_len, ticket_len;
332 uint32_t verify_result, ticket_lifetime;
333 /* TODO is keep_peer_certificate? */
334 char keep_peer_certificate = 1;
Piotr Nowickiab3ecd82020-03-18 15:12:41 +0100335 const uint8_t *end = ssl + len;
Piotr Nowicki4e192002020-03-18 17:27:29 +0100336
337 printf( "\nSession info:\n" );
338
339 if( session_cfg_flag & SESSION_CONFIG_TIME_BIT )
340 {
341 uint64_t start = ( (uint64_t) ssl[0] << 56 ) |
342 ( (uint64_t) ssl[1] << 48 ) |
343 ( (uint64_t) ssl[2] << 40 ) |
344 ( (uint64_t) ssl[3] << 32 ) |
345 ( (uint64_t) ssl[4] << 24 ) |
346 ( (uint64_t) ssl[5] << 16 ) |
347 ( (uint64_t) ssl[6] << 8 ) |
348 ( (uint64_t) ssl[7] );
349 ssl += 8;
350 printf( "\tstart: %lu\n", start );
351 }
352
353 printf( "\tciphersuite: 0x%02X%02X\n", ssl[0], ssl[1] );
354 ssl += 2;
355
356 printf( "\tcompression: 0x%02X\n", *ssl++ );
357 printf( "\tid_len: 0x%02X\n", *ssl++ );
358
359 printf( "\tsession ID: ");
360 print_hex( ssl, 32 );
361 ssl += 32;
362
363 printf( "\tmaster: ");
364 print_hex( ssl, 48 );
365 ssl += 48;
366
367 verify_result = ( (uint32_t) ssl[0] << 24 ) |
368 ( (uint32_t) ssl[1] << 16 ) |
369 ( (uint32_t) ssl[2] << 8 ) |
370 ( (uint32_t) ssl[3] );
371 ssl += 4;
372 printf( "\tverify_result: %u\n", verify_result );
373
374 if( SESSION_CONFIG_CRT_BIT & session_cfg_flag )
375 {
376 if( keep_peer_certificate )
377 {
378 cert_len = ( (uint32_t) ssl[0] << 16 ) |
379 ( (uint32_t) ssl[1] << 8 ) |
380 ( (uint32_t) ssl[2] );
381 ssl += 3;
382 printf_dbg( "cert_len: %u\n", cert_len );
383
384 if( cert_len > 0 )
385 {
386 /* TODO: cert */
387 printf( "TODO: cert\n" );
388 ssl += cert_len;
389 }
390 }
391 else
392 {
393 peer_cert_digest_type = (mbedtls_md_type_t) *ssl++;
394 printf( "\tpeer_cert_digest_type: %d\n", (int)peer_cert_digest_type );
395
396 peer_cert_digest_len = (uint32_t) *ssl++;
397 printf_dbg( "peer_cert_digest_len: %u\n", peer_cert_digest_len );
398
399 if( peer_cert_digest_len > 0 )
400 {
401 /* TODO: peer_cert_digest */
402 printf( "TODO: peer_cert_digest\n" );
403 ssl += peer_cert_digest_len;
404 }
405 }
406 }
407
408 if( SESSION_CONFIG_CLIENT_TICKET_BIT & session_cfg_flag )
409 {
410 ticket_len = ( (uint32_t) ssl[0] << 16 ) |
411 ( (uint32_t) ssl[1] << 8 ) |
412 ( (uint32_t) ssl[2] );
413 ssl += 3;
414 printf_dbg( "ticket_len: %u\n", ticket_len );
415
416 if( ticket_len > 0 )
417 {
418 /* TODO ticket dump */
419 printf( "TODO ticket dump\n" );
420 ssl += ticket_len;
421 }
422
423 ticket_lifetime = ( (uint32_t) ssl[0] << 24 ) |
424 ( (uint32_t) ssl[1] << 16 ) |
425 ( (uint32_t) ssl[2] << 8 ) |
426 ( (uint32_t) ssl[3] );
427 ssl += 4;
428 printf( "\tticket_lifetime: %u\n", ticket_lifetime );
429 }
430
431 if( SESSION_CONFIG_MFL_BIT & session_cfg_flag )
432 {
433 printf( "\tmfl_code: 0x%02X\n", *ssl++ );
434 }
435
436 if( SESSION_CONFIG_TRUNC_HMAC_BIT & session_cfg_flag )
437 {
438 printf( "\ttrunc_hmac: 0x%02X\n", *ssl++ );
439 }
440
441 if( SESSION_CONFIG_ETM_BIT & session_cfg_flag )
442 {
443 printf( "\tencrypt_then_mac: 0x%02X\n", *ssl++ );
444 }
445
446 if( 0 != ( end - ssl ) )
447 {
448 printf_err( "%i bytes left to analyze from session\n", (int32_t)( end - ssl ) );
449 }
Piotr Nowickiab3ecd82020-03-18 15:12:41 +0100450}
451
452/*
453 * This function deserializes and prints to the stdout all obtained information
Piotr Nowicki6b2baf92020-03-17 15:36:52 +0100454 * about the context from provided data. This function was built based on
455 * mbedtls_ssl_context_load(). mbedtls_ssl_context_load() could not be used
456 * due to dependencies on the mbedTLS configuration and the configuration of
457 * the context when serialization was created.
458 *
459 * The data structure in the buffer:
460 * // session sub-structure
461 * opaque session<1..2^32-1>; // see mbedtls_ssl_session_save()
462 * // transform sub-structure
463 * uint8 random[64]; // ServerHello.random+ClientHello.random
464 * uint8 in_cid<0..2^8-1> // Connection ID: expected incoming value
465 * uint8 out_cid<0..2^8-1> // Connection ID: outgoing value to use
466 * // fields from ssl_context
467 * uint32 badmac_seen; // DTLS: number of records with failing MAC
468 * uint64 in_window_top; // DTLS: last validated record seq_num
469 * uint64 in_window; // DTLS: bitmask for replay protection
470 * uint8 disable_datagram_packing; // DTLS: only one record per datagram
471 * uint64 cur_out_ctr; // Record layer: outgoing sequence number
472 * uint16 mtu; // DTLS: path mtu (max outgoing fragment size)
473 * uint8 alpn_chosen<0..2^8-1> // ALPN: negotiated application protocol
474 *
475 * /p ssl pointer to serialized session
476 * /p len number of bytes in the buffer
477 */
Piotr Nowickiab3ecd82020-03-18 15:12:41 +0100478void print_deserialized_ssl_context( const uint8_t *ssl, size_t len )
Piotr Nowicki6b2baf92020-03-17 15:36:52 +0100479{
480 /* TODO: which versions are compatible */
481 /* TODO: add checking len */
Piotr Nowickiab3ecd82020-03-18 15:12:41 +0100482 const uint8_t *end = ssl + len;
Piotr Nowicki6b2baf92020-03-17 15:36:52 +0100483 int session_cfg_flag;
484 int context_cfg_flag;
485 uint32_t session_len;
Piotr Nowickiab3ecd82020-03-18 15:12:41 +0100486 /* TODO is DTLS compiled? */
487 char dtls_used = 1;
Piotr Nowicki6b2baf92020-03-17 15:36:52 +0100488
489 printf( "\nMbed TLS version:\n" );
490
Piotr Nowickiab3ecd82020-03-18 15:12:41 +0100491 printf( "\tmajor:\t%u\n", (uint32_t) *ssl++ );
492 printf( "\tminor:\t%u\n", (uint32_t) *ssl++ );
493 printf( "\tpath:\t%u\n", (uint32_t) *ssl++ );
494
495 printf( "\nEnabled session and context configuration:\n" );
Piotr Nowicki6b2baf92020-03-17 15:36:52 +0100496
497 session_cfg_flag = ( (int) ssl[0] << 8 ) | ( (int) ssl[1] );
498 ssl += 2;
499
500 context_cfg_flag = ( (int) ssl[0] << 16 ) |
501 ( (int) ssl[1] << 8 ) |
502 ( (int) ssl[2] ) ;
503 ssl += 3;
504
Piotr Nowicki6b2baf92020-03-17 15:36:52 +0100505 printf_dbg( "Session config flags 0x%04X\n", session_cfg_flag );
506 printf_dbg( "Context config flags 0x%06X\n", context_cfg_flag );
507
508 print_if_bit( "MBEDTLS_HAVE_TIME", SESSION_CONFIG_TIME_BIT, session_cfg_flag );
509 print_if_bit( "MBEDTLS_X509_CRT_PARSE_C", SESSION_CONFIG_CRT_BIT, session_cfg_flag );
510 print_if_bit( "MBEDTLS_SSL_MAX_FRAGMENT_LENGTH", SESSION_CONFIG_MFL_BIT, session_cfg_flag );
511 print_if_bit( "MBEDTLS_SSL_TRUNCATED_HMAC", SESSION_CONFIG_TRUNC_HMAC_BIT, session_cfg_flag );
512 print_if_bit( "MBEDTLS_SSL_ENCRYPT_THEN_MAC", SESSION_CONFIG_ETM_BIT, session_cfg_flag );
513 print_if_bit( "MBEDTLS_SSL_SESSION_TICKETS", SESSION_CONFIG_TICKET_BIT, session_cfg_flag );
514 print_if_bit( "MBEDTLS_SSL_SESSION_TICKETS and client", SESSION_CONFIG_CLIENT_TICKET_BIT, session_cfg_flag );
515
516 print_if_bit( "MBEDTLS_SSL_DTLS_CONNECTION_ID", CONTEXT_CONFIG_DTLS_CONNECTION_ID_BIT, context_cfg_flag );
517 print_if_bit( "MBEDTLS_SSL_DTLS_BADMAC_LIMIT", CONTEXT_CONFIG_DTLS_BADMAC_LIMIT_BIT, context_cfg_flag );
518 print_if_bit( "MBEDTLS_SSL_DTLS_ANTI_REPLAY", CONTEXT_CONFIG_DTLS_ANTI_REPLAY_BIT, context_cfg_flag );
519 print_if_bit( "MBEDTLS_SSL_ALPN", CONTEXT_CONFIG_ALPN_BIT, context_cfg_flag );
520
521 session_len = ( (uint32_t) ssl[0] << 24 ) |
522 ( (uint32_t) ssl[1] << 16 ) |
523 ( (uint32_t) ssl[2] << 8 ) |
524 ( (uint32_t) ssl[3] );
525 ssl += 4;
526 printf_dbg( "session length %u\n", session_len );
527
Piotr Nowickiab3ecd82020-03-18 15:12:41 +0100528 print_deserialized_ssl_session( ssl, session_len, session_cfg_flag );
529 ssl += session_len;
530
531 /* TODO ssl_populate_transform */
532 printf( "\nRandom bytes: \n");
533 print_hex( ssl, TRANSFORM_RANDBYTE_LEN );
534 printf( "TODO: ssl_populate_transform\n");
535 ssl += TRANSFORM_RANDBYTE_LEN;
536
537 if( CONTEXT_CONFIG_DTLS_CONNECTION_ID_BIT & context_cfg_flag )
538 {
539 uint8_t cid_len;
540 printf( "\nDTLS connection ID:\n" );
541
542 cid_len = *ssl++;
543 printf_dbg( "in_cid_len %u\n", (uint32_t) cid_len );
544
545 printf( "\tin_cid:" );
546 print_hex( ssl, cid_len );
547 ssl += cid_len;
548
549 cid_len = *ssl++;
550 printf_dbg( "out_cid_len %u\n", (uint32_t) cid_len );
551
552 printf( "\tout_cid:" );
553 print_hex( ssl, cid_len );
554 ssl += cid_len;
555 }
556
557 if( CONTEXT_CONFIG_DTLS_BADMAC_LIMIT_BIT & context_cfg_flag )
558 {
559 uint32_t badmac_seen = ( (uint32_t) ssl[0] << 24 ) |
560 ( (uint32_t) ssl[1] << 16 ) |
561 ( (uint32_t) ssl[2] << 8 ) |
562 ( (uint32_t) ssl[3] );
563 ssl += 4;
564 printf( "\tibadmac_seen: %d\n", badmac_seen );
565
566 printf( "\tin_window_top: " );
567 print_hex( ssl, 8 );
568 ssl += 8;
569
570 printf( "\twindow_top: " );
571 print_hex( ssl, 8 );
572 ssl += 8;
573 }
574
575 if( dtls_used )
576 {
577 printf( "\tDTLS datagram packing: %s\n",
578 ( ( *ssl++ ) == 0 ) ?
579 "enabled" : "disabled" );
580 }
581
582 printf( "\tcur_out_ctr: ");
583 print_hex( ssl, 8 );
584 ssl += 8;
585
586 if( dtls_used )
587 {
588 uint16_t mtu = ( ssl[0] << 8 ) | ssl[1];
589 ssl += 2;
590 printf( "\tMTU: %u\n", mtu );
591 }
592
593
594 if( CONTEXT_CONFIG_ALPN_BIT & context_cfg_flag )
595 {
596 uint8_t alpn_len = *ssl++;
597 if( alpn_len > 0 )
598 {
599 if( strlen( (const char*) ssl ) == alpn_len )
600 {
601 printf( "\talpn_chosen: %s\n", ssl );
602 }
603 else
604 {
605 printf_err( "\talpn_len is incorrect\n" );
606 }
607 ssl += alpn_len;
608 }
609 else
610 {
611 printf( "\talpn_chosen: not selected\n" );
612 }
613 }
614
615 /* TODO: check mbedtls_ssl_update_out_pointers( ssl, ssl->transform ); */
616 printf( "TODO: check mbedtls_ssl_update_out_pointers( ssl, ssl->transform );\n" );
617
Piotr Nowicki4e192002020-03-18 17:27:29 +0100618 if( 0 != ( end - ssl ) )
Piotr Nowickiab3ecd82020-03-18 15:12:41 +0100619 {
Piotr Nowicki4e192002020-03-18 17:27:29 +0100620 printf_err( "%i bytes left to analyze from context\n", (int32_t)( end - ssl ) );
Piotr Nowickiab3ecd82020-03-18 15:12:41 +0100621 }
Piotr Nowicki6b2baf92020-03-17 15:36:52 +0100622 printf( "\n" );
623}
624
Piotr Nowicki9370f902020-03-13 14:43:22 +0100625int main( int argc, char *argv[] )
626{
Piotr Nowicki14d31052020-03-16 14:05:22 +0100627 enum { B64BUF_LEN = 4 * 1024 };
Piotr Nowickic7d681c2020-03-17 09:51:31 +0100628 enum { SSLBUF_LEN = B64BUF_LEN * 3 / 4 + 1 };
629
Piotr Nowickiab3ecd82020-03-18 15:12:41 +0100630 uint8_t b64[ B64BUF_LEN ];
631 uint8_t ssl[ SSLBUF_LEN ];
Piotr Nowicki6842c9b2020-03-16 17:52:56 +0100632 uint32_t b64_counter = 0;
633
Piotr Nowicki88ebbbf2020-03-13 16:26:08 +0100634 parse_arguments( argc, argv );
Piotr Nowicki9370f902020-03-13 14:43:22 +0100635
Piotr Nowicki14d31052020-03-16 14:05:22 +0100636 while( NULL != b64_file )
637 {
Piotr Nowickic7d681c2020-03-17 09:51:31 +0100638 size_t ssl_len;
639 size_t b64_len = read_next_b64_code( b64, B64BUF_LEN );
640 if( b64_len > 0)
Piotr Nowicki14d31052020-03-16 14:05:22 +0100641 {
Piotr Nowickic7d681c2020-03-17 09:51:31 +0100642 int ret;
643
Piotr Nowicki4e192002020-03-18 17:27:29 +0100644 printf( "%u. Deserializing...\n", ++b64_counter );
Piotr Nowicki6842c9b2020-03-16 17:52:56 +0100645
646 if( debug )
647 {
Piotr Nowicki6b2baf92020-03-17 15:36:52 +0100648 printf( "\nBase64 code:\n" );
Piotr Nowickic7d681c2020-03-17 09:51:31 +0100649 print_b64( b64, b64_len );
650 }
651
652 ret = mbedtls_base64_decode( ssl, SSLBUF_LEN, &ssl_len, b64, b64_len );
653 if( ret != 0)
654 {
655 mbedtls_strerror( ret, (char*) b64, B64BUF_LEN );
656 printf_err( "base64 code cannot be decoded - %s\n", b64 );
657 continue;
658 }
659
660 if( debug )
661 {
Piotr Nowicki6b2baf92020-03-17 15:36:52 +0100662 printf( "\nDecoded data in hex:\n");
Piotr Nowickic7d681c2020-03-17 09:51:31 +0100663 print_hex( ssl, ssl_len );
Piotr Nowicki6842c9b2020-03-16 17:52:56 +0100664 }
Piotr Nowicki14d31052020-03-16 14:05:22 +0100665
Piotr Nowickiab3ecd82020-03-18 15:12:41 +0100666 print_deserialized_ssl_context( ssl, ssl_len );
Piotr Nowicki6842c9b2020-03-16 17:52:56 +0100667
Piotr Nowicki14d31052020-03-16 14:05:22 +0100668 }
669 else
670 {
671 fclose( b64_file );
672 b64_file = NULL;
673 }
674 }
675
Piotr Nowicki6b2baf92020-03-17 15:36:52 +0100676 printf_dbg( "Finish. Found %u base64 codes\n", b64_counter );
Piotr Nowicki6842c9b2020-03-16 17:52:56 +0100677
Piotr Nowicki9370f902020-03-13 14:43:22 +0100678 return 0;
679}