blob: 1ea02d075b75f01ee7d140ef90511a0e7b5a52d6 [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>
27
28/*
29 * This program version
30 */
31#define PROG_NAME "ssl_base64_dump"
32#define VER_MAJOR 0
33#define VER_MINOR 1
34
35/*
36 * Global values
37 */
38FILE *b64_file = NULL; /* file with base64 codes to deserialize */
39char debug = 0; /* flag for debug messages */
40
41/*
42 * Basic printing functions
43 */
44void print_version( )
45{
46 printf( "%s v%d.%d\n", PROG_NAME, VER_MAJOR, VER_MINOR );
47}
48
49void print_usage( )
50{
51 print_version();
52 printf(
53 "Usage:\n"
54 "\t-f path - Path to the file with base64 code\n"
55 "\t-v - Show version\n"
56 "\t-h - Show this usage\n"
57 "\t-d - Print more information\n"
58 "\n"
59 );
60}
61
62void printf_dbg( const char *str, ... )
63{
64 if( debug )
65 {
66 va_list args;
67 va_start( args, str );
68 printf( "debug: " );
69 vprintf( str, args );
70 fflush( stdout );
71 va_end( args );
72 }
73}
74
75void printf_err( const char *str, ... )
76{
77 va_list args;
78 va_start( args, str );
79 fprintf( stderr, "ERROR: " );
80 vfprintf( stderr, str, args );
81 fflush( stderr );
82 va_end( args );
83}
84
85/*
86 * Exit from the program in case of error
87 */
88void error_exit()
89{
90 if( NULL != b64_file )
91 {
92 fclose( b64_file );
93 }
94 exit( -1 );
95}
96
97/*
98 * This function takes the input arguments of this program
99 */
100void parse_arguments( int argc, char *argv[] )
101{
102 int i = 1;
103
104 if( argc < 2 )
105 {
106 print_usage();
107 error_exit();
108 }
109
110 while( i < argc )
111 {
112 if( strcmp( argv[i], "-d" ) == 0 )
113 {
114 debug = 1;
115 }
116 else if( strcmp( argv[i], "-h" ) == 0 )
117 {
118 print_usage();
119 }
120 else if( strcmp( argv[i], "-v" ) == 0 )
121 {
122 print_version();
123 }
124 else if( strcmp( argv[i], "-f" ) == 0 )
125 {
126 if( ++i >= argc )
127 {
128 printf_err( "File path is empty\n" );
129 error_exit();
130 }
131
132 if( ( b64_file = fopen( argv[i], "r" ) ) == NULL )
133 {
134 printf_err( "Cannot find file \"%s\"\n", argv[i] );
135 error_exit();
136 }
137 }
138 else
139 {
140 print_usage();
141 error_exit();
142 }
143
144 i++;
145 }
146}
147
Piotr Nowicki14d31052020-03-16 14:05:22 +0100148/*
Piotr Nowicki6842c9b2020-03-16 17:52:56 +0100149 * This function prints base64 code to the stdout
150 */
151void print_b64( const char *b, const size_t len )
152{
153 size_t i = 0;
154 const char *end = b + len;
155 while( b < end )
156 {
157 if( ++i > 70 )
158 {
159 printf( "\n" );
160 i = 0;
161 }
162 printf( "%c", *b++ );
163 }
164 printf( "\n" );
165 fflush( stdout );
166}
167
168/*
Piotr Nowicki14d31052020-03-16 14:05:22 +0100169 * Read next base64 code from the 'b64_file'. The 'b64_file' must be opened
170 * previously. After each call to this function, the internal file position
171 * indicator of the global b64_file is advanced.
172 *
173 * /p b64 buffer for input data
174 * /p max_len the maximum number of bytes to write
175 *
176 * \retval number of bytes written in to the b64 buffer or 0 in case no more
177 * data was found
178 */
179size_t read_next_b64_code( char *b64, const size_t max_len )
180{
181 size_t len = 0;
182 uint32_t missed = 0;
183 char pad = 0;
184 char c = 0;
185
186 while( EOF != c )
187 {
188 char c_valid = 0;
189
190 c = (char) fgetc( b64_file );
191
192 if( pad == 1 )
193 {
194 if( c == '=' )
195 {
196 c_valid = 1;
197 pad = 2;
198 }
199 }
200 else if( ( c >= 'A' && c <= 'Z' ) ||
201 ( c >= 'a' && c <= 'z' ) ||
202 ( c >= '0' && c <= '9' ) ||
203 c == '+' || c == '/' )
204 {
205 c_valid = 1;
206 }
207 else if( c == '=' )
208 {
209 c_valid = 1;
210 pad = 1;
211 }
212 else if( c == '-' )
213 {
214 c = '+';
215 c_valid = 1;
216 }
217 else if( c == '_' )
218 {
219 c = '/';
220 c_valid = 1;
221 }
222
223 if( c_valid )
224 {
225 if( len < max_len )
226 {
227 b64[ len++ ] = c;
228 }
229 else
230 {
231 missed++;
232 }
233 }
234 else if( len > 0 )
235 {
236 if( missed > 0 )
237 {
238 printf_err( "Buffer for the base64 code is too small. Missed %u characters\n", missed );
239 }
240 return len;
241 }
242 }
243
244 printf_dbg( "End of file\n" );
245 return 0;
246}
247
Piotr Nowicki9370f902020-03-13 14:43:22 +0100248int main( int argc, char *argv[] )
249{
Piotr Nowicki14d31052020-03-16 14:05:22 +0100250 enum { B64BUF_LEN = 4 * 1024 };
251 char b64[ B64BUF_LEN ];
Piotr Nowicki6842c9b2020-03-16 17:52:56 +0100252 uint32_t b64_counter = 0;
253
Piotr Nowicki88ebbbf2020-03-13 16:26:08 +0100254 parse_arguments( argc, argv );
Piotr Nowicki9370f902020-03-13 14:43:22 +0100255
Piotr Nowicki14d31052020-03-16 14:05:22 +0100256 while( NULL != b64_file )
257 {
258 size_t len = read_next_b64_code( b64, B64BUF_LEN );
259 if( len > 0)
260 {
Piotr Nowicki6842c9b2020-03-16 17:52:56 +0100261 b64_counter++;
262
263 if( debug )
264 {
265 printf( "%u.\n", b64_counter );
266 print_b64( b64, len );
267 }
Piotr Nowicki14d31052020-03-16 14:05:22 +0100268
269 /* TODO: deserializing */
Piotr Nowicki6842c9b2020-03-16 17:52:56 +0100270
271 printf( "\n" );
Piotr Nowicki14d31052020-03-16 14:05:22 +0100272 }
273 else
274 {
275 fclose( b64_file );
276 b64_file = NULL;
277 }
278 }
279
Piotr Nowicki6842c9b2020-03-16 17:52:56 +0100280 printf( "Finish. Found %u base64 codes\n", b64_counter );
281
Piotr Nowicki9370f902020-03-13 14:43:22 +0100282 return 0;
283}