blob: 9c7c21b4bcbc061ab62eaa9e0f1a849da42af505 [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 Nowicki88ebbbf2020-03-13 16:26:08 +010029
30/*
31 * This program version
32 */
33#define PROG_NAME "ssl_base64_dump"
34#define VER_MAJOR 0
35#define VER_MINOR 1
36
37/*
38 * Global values
39 */
40FILE *b64_file = NULL; /* file with base64 codes to deserialize */
41char debug = 0; /* flag for debug messages */
42
43/*
44 * Basic printing functions
45 */
46void print_version( )
47{
48 printf( "%s v%d.%d\n", PROG_NAME, VER_MAJOR, VER_MINOR );
49}
50
51void print_usage( )
52{
53 print_version();
54 printf(
55 "Usage:\n"
56 "\t-f path - Path to the file with base64 code\n"
57 "\t-v - Show version\n"
58 "\t-h - Show this usage\n"
59 "\t-d - Print more information\n"
60 "\n"
61 );
62}
63
64void printf_dbg( const char *str, ... )
65{
66 if( debug )
67 {
68 va_list args;
69 va_start( args, str );
70 printf( "debug: " );
71 vprintf( str, args );
72 fflush( stdout );
73 va_end( args );
74 }
75}
76
77void printf_err( const char *str, ... )
78{
79 va_list args;
80 va_start( args, str );
81 fprintf( stderr, "ERROR: " );
82 vfprintf( stderr, str, args );
83 fflush( stderr );
84 va_end( args );
85}
86
87/*
88 * Exit from the program in case of error
89 */
90void error_exit()
91{
92 if( NULL != b64_file )
93 {
94 fclose( b64_file );
95 }
96 exit( -1 );
97}
98
99/*
100 * This function takes the input arguments of this program
101 */
102void parse_arguments( int argc, char *argv[] )
103{
104 int i = 1;
105
106 if( argc < 2 )
107 {
108 print_usage();
109 error_exit();
110 }
111
112 while( i < argc )
113 {
114 if( strcmp( argv[i], "-d" ) == 0 )
115 {
116 debug = 1;
117 }
118 else if( strcmp( argv[i], "-h" ) == 0 )
119 {
120 print_usage();
121 }
122 else if( strcmp( argv[i], "-v" ) == 0 )
123 {
124 print_version();
125 }
126 else if( strcmp( argv[i], "-f" ) == 0 )
127 {
128 if( ++i >= argc )
129 {
130 printf_err( "File path is empty\n" );
131 error_exit();
132 }
133
134 if( ( b64_file = fopen( argv[i], "r" ) ) == NULL )
135 {
136 printf_err( "Cannot find file \"%s\"\n", argv[i] );
137 error_exit();
138 }
139 }
140 else
141 {
142 print_usage();
143 error_exit();
144 }
145
146 i++;
147 }
148}
149
Piotr Nowicki14d31052020-03-16 14:05:22 +0100150/*
Piotr Nowicki6842c9b2020-03-16 17:52:56 +0100151 * This function prints base64 code to the stdout
152 */
Piotr Nowickic7d681c2020-03-17 09:51:31 +0100153void print_b64( const unsigned char *b, size_t len )
Piotr Nowicki6842c9b2020-03-16 17:52:56 +0100154{
155 size_t i = 0;
Piotr Nowickic7d681c2020-03-17 09:51:31 +0100156 const unsigned char *end = b + len;
157 printf("\t");
Piotr Nowicki6842c9b2020-03-16 17:52:56 +0100158 while( b < end )
159 {
Piotr Nowickic7d681c2020-03-17 09:51:31 +0100160 if( ++i > 75 )
Piotr Nowicki6842c9b2020-03-16 17:52:56 +0100161 {
Piotr Nowickic7d681c2020-03-17 09:51:31 +0100162 printf( "\n\t" );
Piotr Nowicki6842c9b2020-03-16 17:52:56 +0100163 i = 0;
164 }
165 printf( "%c", *b++ );
166 }
167 printf( "\n" );
168 fflush( stdout );
169}
170
171/*
Piotr Nowickic7d681c2020-03-17 09:51:31 +0100172 * This function prints hex code from the buffer to the stdout.
173 */
174void print_hex( const unsigned char *b, size_t len )
175{
176 size_t i = 0;
177 const unsigned char *end = b + len;
178 printf("\t");
179 while( b < end )
180 {
181 printf( "%02X ", (unsigned char) *b++ );
182 if( ++i > 25 )
183 {
184 printf("\n\t");
185 i = 0;
186 }
187 }
188 printf("\n");
189 fflush(stdout);
190}
191
192/*
Piotr Nowicki14d31052020-03-16 14:05:22 +0100193 * Read next base64 code from the 'b64_file'. The 'b64_file' must be opened
194 * previously. After each call to this function, the internal file position
195 * indicator of the global b64_file is advanced.
196 *
197 * /p b64 buffer for input data
198 * /p max_len the maximum number of bytes to write
199 *
200 * \retval number of bytes written in to the b64 buffer or 0 in case no more
201 * data was found
202 */
Piotr Nowickic7d681c2020-03-17 09:51:31 +0100203size_t read_next_b64_code( unsigned char *b64, size_t max_len )
Piotr Nowicki14d31052020-03-16 14:05:22 +0100204{
205 size_t len = 0;
206 uint32_t missed = 0;
207 char pad = 0;
208 char c = 0;
209
210 while( EOF != c )
211 {
212 char c_valid = 0;
213
214 c = (char) fgetc( b64_file );
215
216 if( pad == 1 )
217 {
218 if( c == '=' )
219 {
220 c_valid = 1;
221 pad = 2;
222 }
223 }
224 else if( ( c >= 'A' && c <= 'Z' ) ||
225 ( c >= 'a' && c <= 'z' ) ||
226 ( c >= '0' && c <= '9' ) ||
227 c == '+' || c == '/' )
228 {
229 c_valid = 1;
230 }
231 else if( c == '=' )
232 {
233 c_valid = 1;
234 pad = 1;
235 }
236 else if( c == '-' )
237 {
238 c = '+';
239 c_valid = 1;
240 }
241 else if( c == '_' )
242 {
243 c = '/';
244 c_valid = 1;
245 }
246
247 if( c_valid )
248 {
249 if( len < max_len )
250 {
251 b64[ len++ ] = c;
252 }
253 else
254 {
255 missed++;
256 }
257 }
258 else if( len > 0 )
259 {
260 if( missed > 0 )
261 {
262 printf_err( "Buffer for the base64 code is too small. Missed %u characters\n", missed );
263 }
264 return len;
265 }
266 }
267
268 printf_dbg( "End of file\n" );
269 return 0;
270}
271
Piotr Nowicki9370f902020-03-13 14:43:22 +0100272int main( int argc, char *argv[] )
273{
Piotr Nowicki14d31052020-03-16 14:05:22 +0100274 enum { B64BUF_LEN = 4 * 1024 };
Piotr Nowickic7d681c2020-03-17 09:51:31 +0100275 enum { SSLBUF_LEN = B64BUF_LEN * 3 / 4 + 1 };
276
277 unsigned char b64[ B64BUF_LEN ];
278 unsigned char ssl[ SSLBUF_LEN ];
Piotr Nowicki6842c9b2020-03-16 17:52:56 +0100279 uint32_t b64_counter = 0;
280
Piotr Nowicki88ebbbf2020-03-13 16:26:08 +0100281 parse_arguments( argc, argv );
Piotr Nowicki9370f902020-03-13 14:43:22 +0100282
Piotr Nowicki14d31052020-03-16 14:05:22 +0100283 while( NULL != b64_file )
284 {
Piotr Nowickic7d681c2020-03-17 09:51:31 +0100285 size_t ssl_len;
286 size_t b64_len = read_next_b64_code( b64, B64BUF_LEN );
287 if( b64_len > 0)
Piotr Nowicki14d31052020-03-16 14:05:22 +0100288 {
Piotr Nowickic7d681c2020-03-17 09:51:31 +0100289 int ret;
290
Piotr Nowicki6842c9b2020-03-16 17:52:56 +0100291 b64_counter++;
292
293 if( debug )
294 {
Piotr Nowickic7d681c2020-03-17 09:51:31 +0100295 printf( "%u. Base64 code:\n", b64_counter );
296 print_b64( b64, b64_len );
297 }
298
299 ret = mbedtls_base64_decode( ssl, SSLBUF_LEN, &ssl_len, b64, b64_len );
300 if( ret != 0)
301 {
302 mbedtls_strerror( ret, (char*) b64, B64BUF_LEN );
303 printf_err( "base64 code cannot be decoded - %s\n", b64 );
304 continue;
305 }
306
307 if( debug )
308 {
309 printf( "\n Decoded data in hex:\n");
310 print_hex( ssl, ssl_len );
Piotr Nowicki6842c9b2020-03-16 17:52:56 +0100311 }
Piotr Nowicki14d31052020-03-16 14:05:22 +0100312
313 /* TODO: deserializing */
Piotr Nowicki6842c9b2020-03-16 17:52:56 +0100314
315 printf( "\n" );
Piotr Nowicki14d31052020-03-16 14:05:22 +0100316 }
317 else
318 {
319 fclose( b64_file );
320 b64_file = NULL;
321 }
322 }
323
Piotr Nowicki6842c9b2020-03-16 17:52:56 +0100324 printf( "Finish. Found %u base64 codes\n", b64_counter );
325
Piotr Nowicki9370f902020-03-13 14:43:22 +0100326 return 0;
327}