Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / third_party / mbedtls / repo / programs / util / pem2der.c
1 /*
2  *  Convert PEM to DER
3  *
4  *  Copyright (C) 2006-2015, 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
22 #if !defined(MBEDTLS_CONFIG_FILE)
23 #include "mbedtls/config.h"
24 #else
25 #include MBEDTLS_CONFIG_FILE
26 #endif
27
28 #if defined(MBEDTLS_PLATFORM_C)
29 #include "mbedtls/platform.h"
30 #else
31 #include <stdio.h>
32 #include <stdlib.h>
33 #define mbedtls_free            free
34 #define mbedtls_calloc          calloc
35 #define mbedtls_printf          printf
36 #define mbedtls_exit            exit
37 #define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
38 #define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
39 #endif /* MBEDTLS_PLATFORM_C */
40
41 #if defined(MBEDTLS_BASE64_C) && defined(MBEDTLS_FS_IO)
42 #include "mbedtls/error.h"
43 #include "mbedtls/base64.h"
44
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <string.h>
48 #endif
49
50 #define DFL_FILENAME            "file.pem"
51 #define DFL_OUTPUT_FILENAME     "file.der"
52
53 #define USAGE \
54     "\n usage: pem2der param=<>...\n"                   \
55     "\n acceptable parameters:\n"                       \
56     "    filename=%%s         default: file.pem\n"      \
57     "    output_file=%%s      default: file.der\n"      \
58     "\n"
59
60 #if !defined(MBEDTLS_BASE64_C) || !defined(MBEDTLS_FS_IO)
61 int main( void )
62 {
63     mbedtls_printf("MBEDTLS_BASE64_C and/or MBEDTLS_FS_IO not defined.\n");
64     return( 0 );
65 }
66 #else
67
68 #if defined(MBEDTLS_CHECK_PARAMS)
69 #define mbedtls_exit            exit
70 void mbedtls_param_failed( const char *failure_condition,
71                            const char *file,
72                            int line )
73 {
74     mbedtls_printf( "%s:%i: Input param failed - %s\n",
75                     file, line, failure_condition );
76     mbedtls_exit( MBEDTLS_EXIT_FAILURE );
77 }
78 #endif
79
80 /*
81  * global options
82  */
83 struct options
84 {
85     const char *filename;       /* filename of the input file             */
86     const char *output_file;    /* where to store the output              */
87 } opt;
88
89 int convert_pem_to_der( const unsigned char *input, size_t ilen,
90                         unsigned char *output, size_t *olen )
91 {
92     int ret;
93     const unsigned char *s1, *s2, *end = input + ilen;
94     size_t len = 0;
95
96     s1 = (unsigned char *) strstr( (const char *) input, "-----BEGIN" );
97     if( s1 == NULL )
98         return( -1 );
99
100     s2 = (unsigned char *) strstr( (const char *) input, "-----END" );
101     if( s2 == NULL )
102         return( -1 );
103
104     s1 += 10;
105     while( s1 < end && *s1 != '-' )
106         s1++;
107     while( s1 < end && *s1 == '-' )
108         s1++;
109     if( *s1 == '\r' ) s1++;
110     if( *s1 == '\n' ) s1++;
111
112     if( s2 <= s1 || s2 > end )
113         return( -1 );
114
115     ret = mbedtls_base64_decode( NULL, 0, &len, (const unsigned char *) s1, s2 - s1 );
116     if( ret == MBEDTLS_ERR_BASE64_INVALID_CHARACTER )
117         return( ret );
118
119     if( len > *olen )
120         return( -1 );
121
122     if( ( ret = mbedtls_base64_decode( output, len, &len, (const unsigned char *) s1,
123                                s2 - s1 ) ) != 0 )
124     {
125         return( ret );
126     }
127
128     *olen = len;
129
130     return( 0 );
131 }
132
133 /*
134  * Load all data from a file into a given buffer.
135  */
136 static int load_file( const char *path, unsigned char **buf, size_t *n )
137 {
138     FILE *f;
139     long size;
140
141     if( ( f = fopen( path, "rb" ) ) == NULL )
142         return( -1 );
143
144     fseek( f, 0, SEEK_END );
145     if( ( size = ftell( f ) ) == -1 )
146     {
147         fclose( f );
148         return( -1 );
149     }
150     fseek( f, 0, SEEK_SET );
151
152     *n = (size_t) size;
153
154     if( *n + 1 == 0 ||
155         ( *buf = mbedtls_calloc( 1, *n + 1 ) ) == NULL )
156     {
157         fclose( f );
158         return( -1 );
159     }
160
161     if( fread( *buf, 1, *n, f ) != *n )
162     {
163         fclose( f );
164         free( *buf );
165         *buf = NULL;
166         return( -1 );
167     }
168
169     fclose( f );
170
171     (*buf)[*n] = '\0';
172
173     return( 0 );
174 }
175
176 /*
177  * Write buffer to a file
178  */
179 static int write_file( const char *path, unsigned char *buf, size_t n )
180 {
181     FILE *f;
182
183     if( ( f = fopen( path, "wb" ) ) == NULL )
184         return( -1 );
185
186     if( fwrite( buf, 1, n, f ) != n )
187     {
188         fclose( f );
189         return( -1 );
190     }
191
192     fclose( f );
193     return( 0 );
194 }
195
196 int main( int argc, char *argv[] )
197 {
198     int ret = 1;
199     int exit_code = MBEDTLS_EXIT_FAILURE;
200     unsigned char *pem_buffer = NULL;
201     unsigned char der_buffer[4096];
202     char buf[1024];
203     size_t pem_size, der_size = sizeof(der_buffer);
204     int i;
205     char *p, *q;
206
207     /*
208      * Set to sane values
209      */
210     memset( buf, 0, sizeof(buf) );
211     memset( der_buffer, 0, sizeof(der_buffer) );
212
213     if( argc == 0 )
214     {
215     usage:
216         mbedtls_printf( USAGE );
217         goto exit;
218     }
219
220     opt.filename            = DFL_FILENAME;
221     opt.output_file         = DFL_OUTPUT_FILENAME;
222
223     for( i = 1; i < argc; i++ )
224     {
225
226         p = argv[i];
227         if( ( q = strchr( p, '=' ) ) == NULL )
228             goto usage;
229         *q++ = '\0';
230
231         if( strcmp( p, "filename" ) == 0 )
232             opt.filename = q;
233         else if( strcmp( p, "output_file" ) == 0 )
234             opt.output_file = q;
235         else
236             goto usage;
237     }
238
239     /*
240      * 1.1. Load the PEM file
241      */
242     mbedtls_printf( "\n  . Loading the PEM file ..." );
243     fflush( stdout );
244
245     ret = load_file( opt.filename, &pem_buffer, &pem_size );
246
247     if( ret != 0 )
248     {
249 #ifdef MBEDTLS_ERROR_C
250         mbedtls_strerror( ret, buf, 1024 );
251 #endif
252         mbedtls_printf( " failed\n  !  load_file returned %d - %s\n\n", ret, buf );
253         goto exit;
254     }
255
256     mbedtls_printf( " ok\n" );
257
258     /*
259      * 1.2. Convert from PEM to DER
260      */
261     mbedtls_printf( "  . Converting from PEM to DER ..." );
262     fflush( stdout );
263
264     if( ( ret = convert_pem_to_der( pem_buffer, pem_size, der_buffer, &der_size ) ) != 0 )
265     {
266 #ifdef MBEDTLS_ERROR_C
267         mbedtls_strerror( ret, buf, 1024 );
268 #endif
269         mbedtls_printf( " failed\n  !  convert_pem_to_der %d - %s\n\n", ret, buf );
270         goto exit;
271     }
272
273     mbedtls_printf( " ok\n" );
274
275     /*
276      * 1.3. Write the DER file
277      */
278     mbedtls_printf( "  . Writing the DER file ..." );
279     fflush( stdout );
280
281     ret = write_file( opt.output_file, der_buffer, der_size );
282
283     if( ret != 0 )
284     {
285 #ifdef MBEDTLS_ERROR_C
286         mbedtls_strerror( ret, buf, 1024 );
287 #endif
288         mbedtls_printf( " failed\n  !  write_file returned %d - %s\n\n", ret, buf );
289         goto exit;
290     }
291
292     mbedtls_printf( " ok\n" );
293
294     exit_code = MBEDTLS_EXIT_SUCCESS;
295
296 exit:
297     free( pem_buffer );
298
299 #if defined(_WIN32)
300     mbedtls_printf( "  + Press Enter to exit this program.\n" );
301     fflush( stdout ); getchar();
302 #endif
303
304     return( exit_code );
305 }
306 #endif /* MBEDTLS_BASE64_C && MBEDTLS_FS_IO */