blob: 2ee1f113e2192d7f1e9440e601d9b9e97fc38245 [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/*
149 * Read next base64 code from the 'b64_file'. The 'b64_file' must be opened
150 * previously. After each call to this function, the internal file position
151 * indicator of the global b64_file is advanced.
152 *
153 * /p b64 buffer for input data
154 * /p max_len the maximum number of bytes to write
155 *
156 * \retval number of bytes written in to the b64 buffer or 0 in case no more
157 * data was found
158 */
159size_t read_next_b64_code( char *b64, const size_t max_len )
160{
161 size_t len = 0;
162 uint32_t missed = 0;
163 char pad = 0;
164 char c = 0;
165
166 while( EOF != c )
167 {
168 char c_valid = 0;
169
170 c = (char) fgetc( b64_file );
171
172 if( pad == 1 )
173 {
174 if( c == '=' )
175 {
176 c_valid = 1;
177 pad = 2;
178 }
179 }
180 else if( ( c >= 'A' && c <= 'Z' ) ||
181 ( c >= 'a' && c <= 'z' ) ||
182 ( c >= '0' && c <= '9' ) ||
183 c == '+' || c == '/' )
184 {
185 c_valid = 1;
186 }
187 else if( c == '=' )
188 {
189 c_valid = 1;
190 pad = 1;
191 }
192 else if( c == '-' )
193 {
194 c = '+';
195 c_valid = 1;
196 }
197 else if( c == '_' )
198 {
199 c = '/';
200 c_valid = 1;
201 }
202
203 if( c_valid )
204 {
205 if( len < max_len )
206 {
207 b64[ len++ ] = c;
208 }
209 else
210 {
211 missed++;
212 }
213 }
214 else if( len > 0 )
215 {
216 if( missed > 0 )
217 {
218 printf_err( "Buffer for the base64 code is too small. Missed %u characters\n", missed );
219 }
220 return len;
221 }
222 }
223
224 printf_dbg( "End of file\n" );
225 return 0;
226}
227
Piotr Nowicki9370f902020-03-13 14:43:22 +0100228int main( int argc, char *argv[] )
229{
Piotr Nowicki14d31052020-03-16 14:05:22 +0100230 enum { B64BUF_LEN = 4 * 1024 };
231 char b64[ B64BUF_LEN ];
Piotr Nowicki88ebbbf2020-03-13 16:26:08 +0100232 parse_arguments( argc, argv );
Piotr Nowicki9370f902020-03-13 14:43:22 +0100233
Piotr Nowicki14d31052020-03-16 14:05:22 +0100234 while( NULL != b64_file )
235 {
236 size_t len = read_next_b64_code( b64, B64BUF_LEN );
237 if( len > 0)
238 {
239
240 /* TODO: deserializing */
241 }
242 else
243 {
244 fclose( b64_file );
245 b64_file = NULL;
246 }
247 }
248
Piotr Nowicki9370f902020-03-13 14:43:22 +0100249 return 0;
250}