1 /*
2  *  RSA/SHA-256 signature verification program
3  *
4  *  Copyright The Mbed TLS Contributors
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 
20 #if !defined(MBEDTLS_CONFIG_FILE)
21 #include "mbedtls/config.h"
22 #else
23 #include MBEDTLS_CONFIG_FILE
24 #endif
25 
26 #if defined(MBEDTLS_PLATFORM_C)
27 #include "mbedtls/platform.h"
28 #else
29 #include <stdio.h>
30 #include <stdlib.h>
31 #define mbedtls_printf          printf
32 #define mbedtls_snprintf        snprintf
33 #define mbedtls_exit            exit
34 #define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
35 #define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
36 #endif /* MBEDTLS_PLATFORM_C */
37 
38 #if !defined(MBEDTLS_BIGNUM_C) || !defined(MBEDTLS_RSA_C) ||  \
39     !defined(MBEDTLS_SHA256_C) || !defined(MBEDTLS_MD_C) || \
40     !defined(MBEDTLS_FS_IO)
main(void)41 int main( void )
42 {
43     mbedtls_printf("MBEDTLS_BIGNUM_C and/or MBEDTLS_RSA_C and/or "
44             "MBEDTLS_MD_C and/or "
45             "MBEDTLS_SHA256_C and/or MBEDTLS_FS_IO not defined.\n");
46     mbedtls_exit( 0 );
47 }
48 #else
49 
50 #include "mbedtls/rsa.h"
51 #include "mbedtls/md.h"
52 
53 #include <stdio.h>
54 #include <string.h>
55 
56 
main(int argc,char * argv[])57 int main( int argc, char *argv[] )
58 {
59     FILE *f;
60     int ret = 1;
61     unsigned c;
62     int exit_code = MBEDTLS_EXIT_FAILURE;
63     size_t i;
64     mbedtls_rsa_context rsa;
65     unsigned char hash[32];
66     unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
67     char filename[512];
68 
69     mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 );
70 
71     if( argc != 2 )
72     {
73         mbedtls_printf( "usage: rsa_verify <filename>\n" );
74 
75 #if defined(_WIN32)
76         mbedtls_printf( "\n" );
77 #endif
78 
79         goto exit;
80     }
81 
82     mbedtls_printf( "\n  . Reading public key from rsa_pub.txt" );
83     fflush( stdout );
84 
85     if( ( f = fopen( "rsa_pub.txt", "rb" ) ) == NULL )
86     {
87         mbedtls_printf( " failed\n  ! Could not open rsa_pub.txt\n" \
88                 "  ! Please run rsa_genkey first\n\n" );
89         goto exit;
90     }
91 
92     if( ( ret = mbedtls_mpi_read_file( &rsa.N, 16, f ) ) != 0 ||
93         ( ret = mbedtls_mpi_read_file( &rsa.E, 16, f ) ) != 0 )
94     {
95         mbedtls_printf( " failed\n  ! mbedtls_mpi_read_file returned %d\n\n", ret );
96         fclose( f );
97         goto exit;
98     }
99 
100     rsa.len = ( mbedtls_mpi_bitlen( &rsa.N ) + 7 ) >> 3;
101 
102     fclose( f );
103 
104     /*
105      * Extract the RSA signature from the text file
106      */
107     mbedtls_snprintf( filename, sizeof(filename), "%s.sig", argv[1] );
108 
109     if( ( f = fopen( filename, "rb" ) ) == NULL )
110     {
111         mbedtls_printf( "\n  ! Could not open %s\n\n", filename );
112         goto exit;
113     }
114 
115     i = 0;
116     while( fscanf( f, "%02X", (unsigned int*) &c ) > 0 &&
117            i < (int) sizeof( buf ) )
118         buf[i++] = (unsigned char) c;
119 
120     fclose( f );
121 
122     if( i != rsa.len )
123     {
124         mbedtls_printf( "\n  ! Invalid RSA signature format\n\n" );
125         goto exit;
126     }
127 
128     /*
129      * Compute the SHA-256 hash of the input file and
130      * verify the signature
131      */
132     mbedtls_printf( "\n  . Verifying the RSA/SHA-256 signature" );
133     fflush( stdout );
134 
135     if( ( ret = mbedtls_md_file(
136                     mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ),
137                     argv[1], hash ) ) != 0 )
138     {
139         mbedtls_printf( " failed\n  ! Could not open or read %s\n\n", argv[1] );
140         goto exit;
141     }
142 
143     if( ( ret = mbedtls_rsa_pkcs1_verify( &rsa, NULL, NULL, MBEDTLS_RSA_PUBLIC,
144                                   MBEDTLS_MD_SHA256, 20, hash, buf ) ) != 0 )
145     {
146         mbedtls_printf( " failed\n  ! mbedtls_rsa_pkcs1_verify returned -0x%0x\n\n", (unsigned int) -ret );
147         goto exit;
148     }
149 
150     mbedtls_printf( "\n  . OK (the signature is valid)\n\n" );
151 
152     exit_code = MBEDTLS_EXIT_SUCCESS;
153 
154 exit:
155 
156     mbedtls_rsa_free( &rsa );
157 
158 #if defined(_WIN32)
159     mbedtls_printf( "  + Press Enter to exit this program.\n" );
160     fflush( stdout ); getchar();
161 #endif
162 
163     mbedtls_exit( exit_code );
164 }
165 #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_RSA_C && MBEDTLS_SHA256_C &&
166           MBEDTLS_FS_IO */
167