Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / third_party / mbedtls / repo / programs / x509 / cert_req.c
1 /*
2  *  Certificate request generation
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_printf          printf
34 #define mbedtls_exit            exit
35 #define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
36 #define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
37 #endif /* MBEDTLS_PLATFORM_C */
38
39 #if !defined(MBEDTLS_X509_CSR_WRITE_C) || !defined(MBEDTLS_FS_IO) ||  \
40     !defined(MBEDTLS_PK_PARSE_C) || !defined(MBEDTLS_SHA256_C) || \
41     !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_CTR_DRBG_C) || \
42     !defined(MBEDTLS_PEM_WRITE_C)
43 int main( void )
44 {
45     mbedtls_printf( "MBEDTLS_X509_CSR_WRITE_C and/or MBEDTLS_FS_IO and/or "
46             "MBEDTLS_PK_PARSE_C and/or MBEDTLS_SHA256_C and/or "
47             "MBEDTLS_ENTROPY_C and/or MBEDTLS_CTR_DRBG_C "
48             "not defined.\n");
49     return( 0 );
50 }
51 #else
52
53 #include "mbedtls/x509_csr.h"
54 #include "mbedtls/entropy.h"
55 #include "mbedtls/ctr_drbg.h"
56 #include "mbedtls/error.h"
57
58 #include <stdio.h>
59 #include <stdlib.h>
60 #include <string.h>
61
62 #define DFL_FILENAME            "keyfile.key"
63 #define DFL_PASSWORD            NULL
64 #define DFL_DEBUG_LEVEL         0
65 #define DFL_OUTPUT_FILENAME     "cert.req"
66 #define DFL_SUBJECT_NAME        "CN=Cert,O=mbed TLS,C=UK"
67 #define DFL_KEY_USAGE           0
68 #define DFL_FORCE_KEY_USAGE     0
69 #define DFL_NS_CERT_TYPE        0
70 #define DFL_FORCE_NS_CERT_TYPE  0
71 #define DFL_MD_ALG              MBEDTLS_MD_SHA256
72
73 #define USAGE \
74     "\n usage: cert_req param=<>...\n"                  \
75     "\n acceptable parameters:\n"                       \
76     "    filename=%%s         default: keyfile.key\n"   \
77     "    password=%%s         default: NULL\n"          \
78     "    debug_level=%%d      default: 0 (disabled)\n"  \
79     "    output_file=%%s      default: cert.req\n"      \
80     "    subject_name=%%s     default: CN=Cert,O=mbed TLS,C=UK\n"   \
81     "    key_usage=%%s        default: (empty)\n"       \
82     "                        Comma-separated-list of values:\n"     \
83     "                          digital_signature\n"     \
84     "                          non_repudiation\n"       \
85     "                          key_encipherment\n"      \
86     "                          data_encipherment\n"     \
87     "                          key_agreement\n"         \
88     "                          key_cert_sign\n"  \
89     "                          crl_sign\n"              \
90     "    force_key_usage=0/1  default: off\n"           \
91     "                          Add KeyUsage even if it is empty\n"  \
92     "    ns_cert_type=%%s     default: (empty)\n"       \
93     "                        Comma-separated-list of values:\n"     \
94     "                          ssl_client\n"            \
95     "                          ssl_server\n"            \
96     "                          email\n"                 \
97     "                          object_signing\n"        \
98     "                          ssl_ca\n"                \
99     "                          email_ca\n"              \
100     "                          object_signing_ca\n"     \
101     "    force_ns_cert_type=0/1 default: off\n"         \
102     "                          Add NsCertType even if it is empty\n"    \
103     "    md=%%s               default: SHA256\n"       \
104     "                          possible values:\n"     \
105     "                          MD4, MD5, SHA1\n"       \
106     "                          SHA224, SHA256\n"       \
107     "                          SHA384, SHA512\n"       \
108     "\n"
109
110 #if defined(MBEDTLS_CHECK_PARAMS)
111 void mbedtls_param_failed( const char *failure_condition,
112                            const char *file,
113                            int line )
114 {
115     mbedtls_printf( "%s:%i: Input param failed - %s\n",
116                     file, line, failure_condition );
117     mbedtls_exit( MBEDTLS_EXIT_FAILURE );
118 }
119 #endif
120
121 /*
122  * global options
123  */
124 struct options
125 {
126     const char *filename;       /* filename of the key file             */
127     const char *password;       /* password for the key file            */
128     int debug_level;            /* level of debugging                   */
129     const char *output_file;    /* where to store the constructed key file  */
130     const char *subject_name;   /* subject name for certificate request */
131     unsigned char key_usage;    /* key usage flags                      */
132     int force_key_usage;        /* Force adding the KeyUsage extension  */
133     unsigned char ns_cert_type; /* NS cert type                         */
134     int force_ns_cert_type;     /* Force adding NsCertType extension    */
135     mbedtls_md_type_t md_alg;   /* Hash algorithm used for signature.   */
136 } opt;
137
138 int write_certificate_request( mbedtls_x509write_csr *req, const char *output_file,
139                                int (*f_rng)(void *, unsigned char *, size_t),
140                                void *p_rng )
141 {
142     int ret;
143     FILE *f;
144     unsigned char output_buf[4096];
145     size_t len = 0;
146
147     memset( output_buf, 0, 4096 );
148     if( ( ret = mbedtls_x509write_csr_pem( req, output_buf, 4096, f_rng, p_rng ) ) < 0 )
149         return( ret );
150
151     len = strlen( (char *) output_buf );
152
153     if( ( f = fopen( output_file, "w" ) ) == NULL )
154         return( -1 );
155
156     if( fwrite( output_buf, 1, len, f ) != len )
157     {
158         fclose( f );
159         return( -1 );
160     }
161
162     fclose( f );
163
164     return( 0 );
165 }
166
167 int main( int argc, char *argv[] )
168 {
169     int ret = 1;
170     int exit_code = MBEDTLS_EXIT_FAILURE;
171     mbedtls_pk_context key;
172     char buf[1024];
173     int i;
174     char *p, *q, *r;
175     mbedtls_x509write_csr req;
176     mbedtls_entropy_context entropy;
177     mbedtls_ctr_drbg_context ctr_drbg;
178     const char *pers = "csr example app";
179
180     /*
181      * Set to sane values
182      */
183     mbedtls_x509write_csr_init( &req );
184     mbedtls_pk_init( &key );
185     mbedtls_ctr_drbg_init( &ctr_drbg );
186     memset( buf, 0, sizeof( buf ) );
187
188     if( argc == 0 )
189     {
190     usage:
191         mbedtls_printf( USAGE );
192         goto exit;
193     }
194
195     opt.filename            = DFL_FILENAME;
196     opt.password            = DFL_PASSWORD;
197     opt.debug_level         = DFL_DEBUG_LEVEL;
198     opt.output_file         = DFL_OUTPUT_FILENAME;
199     opt.subject_name        = DFL_SUBJECT_NAME;
200     opt.key_usage           = DFL_KEY_USAGE;
201     opt.force_key_usage     = DFL_FORCE_KEY_USAGE;
202     opt.ns_cert_type        = DFL_NS_CERT_TYPE;
203     opt.force_ns_cert_type  = DFL_FORCE_NS_CERT_TYPE;
204     opt.md_alg              = DFL_MD_ALG;
205
206     for( i = 1; i < argc; i++ )
207     {
208
209         p = argv[i];
210         if( ( q = strchr( p, '=' ) ) == NULL )
211             goto usage;
212         *q++ = '\0';
213
214         if( strcmp( p, "filename" ) == 0 )
215             opt.filename = q;
216         else if( strcmp( p, "password" ) == 0 )
217             opt.password = q;
218         else if( strcmp( p, "output_file" ) == 0 )
219             opt.output_file = q;
220         else if( strcmp( p, "debug_level" ) == 0 )
221         {
222             opt.debug_level = atoi( q );
223             if( opt.debug_level < 0 || opt.debug_level > 65535 )
224                 goto usage;
225         }
226         else if( strcmp( p, "subject_name" ) == 0 )
227         {
228             opt.subject_name = q;
229         }
230         else if( strcmp( p, "md" ) == 0 )
231         {
232             if( strcmp( q, "SHA256" ) == 0 )
233             {
234                 opt.md_alg = MBEDTLS_MD_SHA256;
235             }
236             else if( strcmp( q, "SHA224" ) == 0 )
237             {
238                 opt.md_alg = MBEDTLS_MD_SHA224;
239             }
240             else
241 #if defined(MBEDTLS_MD5_C)
242             if( strcmp( q, "MD5" ) == 0 )
243             {
244                 opt.md_alg = MBEDTLS_MD_MD5;
245             }
246             else
247 #endif /* MBEDTLS_MD5_C */
248 #if defined(MBEDTLS_MD4_C)
249             if( strcmp( q, "MD4" ) == 0 )
250             {
251                 opt.md_alg = MBEDTLS_MD_MD4;
252             }
253             else
254 #endif /* MBEDTLS_MD5_C */
255 #if defined(MBEDTLS_SHA1_C)
256             if( strcmp( q, "SHA1" ) == 0 )
257             {
258                 opt.md_alg = MBEDTLS_MD_SHA1;
259             }
260             else
261 #endif /* MBEDTLS_SHA1_C */
262 #if defined(MBEDTLS_SHA512_C)
263             if( strcmp( q, "SHA384" ) == 0 )
264             {
265                 opt.md_alg = MBEDTLS_MD_SHA384;
266             }
267             else
268             if( strcmp( q, "SHA512" ) == 0 )
269             {
270                 opt.md_alg = MBEDTLS_MD_SHA512;
271             }
272             else
273 #endif /* MBEDTLS_SHA512_C */
274             {
275                 goto usage;
276             }
277         }
278         else if( strcmp( p, "key_usage" ) == 0 )
279         {
280             while( q != NULL )
281             {
282                 if( ( r = strchr( q, ',' ) ) != NULL )
283                     *r++ = '\0';
284
285                 if( strcmp( q, "digital_signature" ) == 0 )
286                     opt.key_usage |= MBEDTLS_X509_KU_DIGITAL_SIGNATURE;
287                 else if( strcmp( q, "non_repudiation" ) == 0 )
288                     opt.key_usage |= MBEDTLS_X509_KU_NON_REPUDIATION;
289                 else if( strcmp( q, "key_encipherment" ) == 0 )
290                     opt.key_usage |= MBEDTLS_X509_KU_KEY_ENCIPHERMENT;
291                 else if( strcmp( q, "data_encipherment" ) == 0 )
292                     opt.key_usage |= MBEDTLS_X509_KU_DATA_ENCIPHERMENT;
293                 else if( strcmp( q, "key_agreement" ) == 0 )
294                     opt.key_usage |= MBEDTLS_X509_KU_KEY_AGREEMENT;
295                 else if( strcmp( q, "key_cert_sign" ) == 0 )
296                     opt.key_usage |= MBEDTLS_X509_KU_KEY_CERT_SIGN;
297                 else if( strcmp( q, "crl_sign" ) == 0 )
298                     opt.key_usage |= MBEDTLS_X509_KU_CRL_SIGN;
299                 else
300                     goto usage;
301
302                 q = r;
303             }
304         }
305         else if( strcmp( p, "force_key_usage" ) == 0 )
306         {
307             switch( atoi( q ) )
308             {
309                 case 0: opt.force_key_usage = 0; break;
310                 case 1: opt.force_key_usage = 1; break;
311                 default: goto usage;
312             }
313         }
314         else if( strcmp( p, "ns_cert_type" ) == 0 )
315         {
316             while( q != NULL )
317             {
318                 if( ( r = strchr( q, ',' ) ) != NULL )
319                     *r++ = '\0';
320
321                 if( strcmp( q, "ssl_client" ) == 0 )
322                     opt.ns_cert_type |= MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT;
323                 else if( strcmp( q, "ssl_server" ) == 0 )
324                     opt.ns_cert_type |= MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER;
325                 else if( strcmp( q, "email" ) == 0 )
326                     opt.ns_cert_type |= MBEDTLS_X509_NS_CERT_TYPE_EMAIL;
327                 else if( strcmp( q, "object_signing" ) == 0 )
328                     opt.ns_cert_type |= MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING;
329                 else if( strcmp( q, "ssl_ca" ) == 0 )
330                     opt.ns_cert_type |= MBEDTLS_X509_NS_CERT_TYPE_SSL_CA;
331                 else if( strcmp( q, "email_ca" ) == 0 )
332                     opt.ns_cert_type |= MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA;
333                 else if( strcmp( q, "object_signing_ca" ) == 0 )
334                     opt.ns_cert_type |= MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA;
335                 else
336                     goto usage;
337
338                 q = r;
339             }
340         }
341         else if( strcmp( p, "force_ns_cert_type" ) == 0 )
342         {
343             switch( atoi( q ) )
344             {
345                 case 0: opt.force_ns_cert_type = 0; break;
346                 case 1: opt.force_ns_cert_type = 1; break;
347                 default: goto usage;
348             }
349         }
350         else
351             goto usage;
352     }
353
354     mbedtls_x509write_csr_set_md_alg( &req, opt.md_alg );
355
356     if( opt.key_usage || opt.force_key_usage == 1 )
357         mbedtls_x509write_csr_set_key_usage( &req, opt.key_usage );
358
359     if( opt.ns_cert_type || opt.force_ns_cert_type == 1 )
360         mbedtls_x509write_csr_set_ns_cert_type( &req, opt.ns_cert_type );
361
362     /*
363      * 0. Seed the PRNG
364      */
365     mbedtls_printf( "  . Seeding the random number generator..." );
366     fflush( stdout );
367
368     mbedtls_entropy_init( &entropy );
369     if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
370                                (const unsigned char *) pers,
371                                strlen( pers ) ) ) != 0 )
372     {
373         mbedtls_printf( " failed\n  !  mbedtls_ctr_drbg_seed returned %d", ret );
374         goto exit;
375     }
376
377     mbedtls_printf( " ok\n" );
378
379     /*
380      * 1.0. Check the subject name for validity
381      */
382     mbedtls_printf( "  . Checking subject name..." );
383     fflush( stdout );
384
385     if( ( ret = mbedtls_x509write_csr_set_subject_name( &req, opt.subject_name ) ) != 0 )
386     {
387         mbedtls_printf( " failed\n  !  mbedtls_x509write_csr_set_subject_name returned %d", ret );
388         goto exit;
389     }
390
391     mbedtls_printf( " ok\n" );
392
393     /*
394      * 1.1. Load the key
395      */
396     mbedtls_printf( "  . Loading the private key ..." );
397     fflush( stdout );
398
399     ret = mbedtls_pk_parse_keyfile( &key, opt.filename, opt.password );
400
401     if( ret != 0 )
402     {
403         mbedtls_printf( " failed\n  !  mbedtls_pk_parse_keyfile returned %d", ret );
404         goto exit;
405     }
406
407     mbedtls_x509write_csr_set_key( &req, &key );
408
409     mbedtls_printf( " ok\n" );
410
411     /*
412      * 1.2. Writing the request
413      */
414     mbedtls_printf( "  . Writing the certificate request ..." );
415     fflush( stdout );
416
417     if( ( ret = write_certificate_request( &req, opt.output_file,
418                                            mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 )
419     {
420         mbedtls_printf( " failed\n  !  write_certifcate_request %d", ret );
421         goto exit;
422     }
423
424     mbedtls_printf( " ok\n" );
425
426     exit_code = MBEDTLS_EXIT_SUCCESS;
427
428 exit:
429
430     if( exit_code != MBEDTLS_EXIT_SUCCESS )
431     {
432 #ifdef MBEDTLS_ERROR_C
433         mbedtls_strerror( ret, buf, sizeof( buf ) );
434         mbedtls_printf( " - %s\n", buf );
435 #else
436         mbedtls_printf("\n");
437 #endif
438     }
439
440     mbedtls_x509write_csr_free( &req );
441     mbedtls_pk_free( &key );
442     mbedtls_ctr_drbg_free( &ctr_drbg );
443     mbedtls_entropy_free( &entropy );
444
445 #if defined(_WIN32)
446     mbedtls_printf( "  + Press Enter to exit this program.\n" );
447     fflush( stdout ); getchar();
448 #endif
449
450     return( exit_code );
451 }
452 #endif /* MBEDTLS_X509_CSR_WRITE_C && MBEDTLS_PK_PARSE_C && MBEDTLS_FS_IO &&
453           MBEDTLS_ENTROPY_C && MBEDTLS_CTR_DRBG_C && MBEDTLS_PEM_WRITE_C */