1 /*
2  *  Public key-based signature creation program
3  *
4  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5  *  SPDX-License-Identifier: GPL-2.0
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License along
18  *  with this program; if not, write to the Free Software Foundation, Inc.,
19  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  *  This file is part of mbed TLS (https://tls.mbed.org)
22  */
23 
24 #if !defined(MBEDTLS_CONFIG_FILE)
25 #include "mbedtls/config.h"
26 #else
27 #include MBEDTLS_CONFIG_FILE
28 #endif
29 
30 #if defined(MBEDTLS_PLATFORM_C)
31 #include "mbedtls/platform.h"
32 #else
33 #include <stdio.h>
34 #include <stdlib.h>
35 #define mbedtls_snprintf        snprintf
36 #define mbedtls_printf          printf
37 #define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
38 #define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
39 #endif /* MBEDTLS_PLATFORM_C */
40 
41 #if !defined(MBEDTLS_BIGNUM_C) || !defined(MBEDTLS_ENTROPY_C) ||  \
42     !defined(MBEDTLS_SHA256_C) || !defined(MBEDTLS_MD_C) || \
43     !defined(MBEDTLS_PK_PARSE_C) || !defined(MBEDTLS_FS_IO) ||    \
44     !defined(MBEDTLS_CTR_DRBG_C)
main(void)45 int main( void )
46 {
47     mbedtls_printf("MBEDTLS_BIGNUM_C and/or MBEDTLS_ENTROPY_C and/or "
48            "MBEDTLS_SHA256_C and/or MBEDTLS_MD_C and/or "
49            "MBEDTLS_PK_PARSE_C and/or MBEDTLS_FS_IO and/or "
50            "MBEDTLS_CTR_DRBG_C not defined.\n");
51     return( 0 );
52 }
53 #else
54 
55 #include "mbedtls/error.h"
56 #include "mbedtls/entropy.h"
57 #include "mbedtls/ctr_drbg.h"
58 #include "mbedtls/md.h"
59 #include "mbedtls/pk.h"
60 
61 #include <stdio.h>
62 #include <string.h>
63 
main(int argc,char * argv[])64 int main( int argc, char *argv[] )
65 {
66     FILE *f;
67     int ret = 1;
68     int exit_code = MBEDTLS_EXIT_FAILURE;
69     mbedtls_pk_context pk;
70     mbedtls_entropy_context entropy;
71     mbedtls_ctr_drbg_context ctr_drbg;
72     unsigned char hash[32];
73     unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
74     char filename[512];
75     const char *pers = "mbedtls_pk_sign";
76     size_t olen = 0;
77 
78     mbedtls_entropy_init( &entropy );
79     mbedtls_ctr_drbg_init( &ctr_drbg );
80     mbedtls_pk_init( &pk );
81 
82     if( argc != 3 )
83     {
84         mbedtls_printf( "usage: mbedtls_pk_sign <key_file> <filename>\n" );
85 
86 #if defined(_WIN32)
87         mbedtls_printf( "\n" );
88 #endif
89 
90         goto exit;
91     }
92 
93     mbedtls_printf( "\n  . Seeding the random number generator..." );
94     fflush( stdout );
95 
96     if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
97                                (const unsigned char *) pers,
98                                strlen( pers ) ) ) != 0 )
99     {
100         mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned -0x%04x\n", -ret );
101         goto exit;
102     }
103 
104     mbedtls_printf( "\n  . Reading private key from '%s'", argv[1] );
105     fflush( stdout );
106 
107     if( ( ret = mbedtls_pk_parse_keyfile( &pk, argv[1], "" ) ) != 0 )
108     {
109         mbedtls_printf( " failed\n  ! Could not parse '%s'\n", argv[1] );
110         goto exit;
111     }
112 
113     /*
114      * Compute the SHA-256 hash of the input file,
115      * then calculate the signature of the hash.
116      */
117     mbedtls_printf( "\n  . Generating the SHA-256 signature" );
118     fflush( stdout );
119 
120     if( ( ret = mbedtls_md_file(
121                     mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ),
122                     argv[2], hash ) ) != 0 )
123     {
124         mbedtls_printf( " failed\n  ! Could not open or read %s\n\n", argv[2] );
125         goto exit;
126     }
127 
128     if( ( ret = mbedtls_pk_sign( &pk, MBEDTLS_MD_SHA256, hash, 0, buf, &olen,
129                          mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 )
130     {
131         mbedtls_printf( " failed\n  ! mbedtls_pk_sign returned -0x%04x\n", -ret );
132         goto exit;
133     }
134 
135     /*
136      * Write the signature into <filename>.sig
137      */
138     mbedtls_snprintf( filename, sizeof(filename), "%s.sig", argv[2] );
139 
140     if( ( f = fopen( filename, "wb+" ) ) == NULL )
141     {
142         mbedtls_printf( " failed\n  ! Could not create %s\n\n", filename );
143         goto exit;
144     }
145 
146     if( fwrite( buf, 1, olen, f ) != olen )
147     {
148         mbedtls_printf( "failed\n  ! fwrite failed\n\n" );
149         fclose( f );
150         goto exit;
151     }
152 
153     fclose( f );
154 
155     mbedtls_printf( "\n  . Done (created \"%s\")\n\n", filename );
156 
157     exit_code = MBEDTLS_EXIT_SUCCESS;
158 
159 exit:
160     mbedtls_pk_free( &pk );
161     mbedtls_ctr_drbg_free( &ctr_drbg );
162     mbedtls_entropy_free( &entropy );
163 
164 #if defined(MBEDTLS_ERROR_C)
165     if( exit_code != MBEDTLS_EXIT_SUCCESS )
166     {
167         mbedtls_strerror( ret, (char *) buf, sizeof(buf) );
168         mbedtls_printf( "  !  Last error was: %s\n", buf );
169     }
170 #endif
171 
172 #if defined(_WIN32)
173     mbedtls_printf( "  + Press Enter to exit this program.\n" );
174     fflush( stdout ); getchar();
175 #endif
176 
177     return( exit_code );
178 }
179 #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ENTROPY_C &&
180           MBEDTLS_SHA256_C && MBEDTLS_PK_PARSE_C && MBEDTLS_FS_IO &&
181           MBEDTLS_CTR_DRBG_C */
182