blob: 31f1dfc02dd4a9acc67b2fbdcfbf2c3eb03fde61 [file] [log] [blame]
Paul Bakker4fc45522010-03-18 20:11:58 +00001/*
2 * Certificate reading application
3 *
Paul Bakker84f12b72010-07-18 10:13:04 +00004 * Copyright (C) 2006-2010, Brainspark B.V.
Paul Bakkerb96f1542010-07-18 20:36:00 +00005 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
Paul Bakker84f12b72010-07-18 10:13:04 +00007 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
Paul Bakkerb96f1542010-07-18 20:36:00 +00008 *
Paul Bakker4fc45522010-03-18 20:11:58 +00009 * All rights reserved.
10 *
Paul Bakker4fc45522010-03-18 20:11:58 +000011 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25
26#ifndef _CRT_SECURE_NO_DEPRECATE
27#define _CRT_SECURE_NO_DEPRECATE 1
28#endif
29
30#include <string.h>
31#include <stdlib.h>
32#include <stdio.h>
33
34#include "polarssl/havege.h"
35#include "polarssl/net.h"
36#include "polarssl/ssl.h"
37#include "polarssl/x509.h"
38
39#define MODE_NONE 0
40#define MODE_FILE 1
41#define MODE_SSL 2
42
43#define DFL_MODE MODE_NONE
44#define DFL_FILENAME "cert.crt"
45#define DFL_SERVER_NAME "localhost"
46#define DFL_SERVER_PORT 4433
47#define DFL_DEBUG_LEVEL 0
48
49/*
50 * global options
51 */
52struct options
53{
54 int mode; /* the mode to run the application in */
55 char *filename; /* filename of the certificate file */
56 char *server_name; /* hostname of the server (client only) */
57 int server_port; /* port on which the ssl service runs */
58 int debug_level; /* level of debugging */
59} opt;
60
61void my_debug( void *ctx, int level, const char *str )
62{
63 if( level < opt.debug_level )
64 {
65 fprintf( (FILE *) ctx, "%s", str );
66 fflush( (FILE *) ctx );
67 }
68}
69
70#define USAGE \
71 "\n usage: cert_app param=<>...\n" \
72 "\n acceptable parameters:\n" \
73 " mode=file|ssl default: none\n" \
74 " filename=%%s default: cert.crt\n" \
75 " server_name=%%s default: localhost\n" \
76 " server_port=%%d default: 4433\n" \
77 " debug_level=%%d default: 0 (disabled)\n" \
78 "\n"
79
80int main( int argc, char *argv[] )
81{
82 int ret = 0, server_fd;
83 unsigned char buf[1024];
84 havege_state hs;
85 ssl_context ssl;
86 ssl_session ssn;
87 x509_cert clicert;
88 rsa_context rsa;
89 int i, j, n;
90 char *p, *q;
91
92 if( argc == 0 )
93 {
94 usage:
95 printf( USAGE );
96 goto exit;
97 }
98
99 opt.mode = DFL_MODE;
100 opt.filename = DFL_FILENAME;
101 opt.server_name = DFL_SERVER_NAME;
102 opt.server_port = DFL_SERVER_PORT;
103 opt.debug_level = DFL_DEBUG_LEVEL;
104
105 for( i = 1; i < argc; i++ )
106 {
107 n = strlen( argv[i] );
108
109 for( j = 0; j < n; j++ )
110 {
111 if( argv[i][j] >= 'A' && argv[i][j] <= 'Z' )
112 argv[i][j] |= 0x20;
113 }
114
115 p = argv[i];
116 if( ( q = strchr( p, '=' ) ) == NULL )
117 goto usage;
118 *q++ = '\0';
119
120 if( strcmp( p, "mode" ) == 0 )
121 {
122 if( strcmp( q, "file" ) == 0 )
123 opt.mode = MODE_FILE;
124 else if( strcmp( q, "ssl" ) == 0 )
125 opt.mode = MODE_SSL;
126 else
127 goto usage;
128 }
129 else if( strcmp( p, "filename" ) == 0 )
130 opt.filename = q;
131 else if( strcmp( p, "server_name" ) == 0 )
132 opt.server_name = q;
133 else if( strcmp( p, "server_port" ) == 0 )
134 {
135 opt.server_port = atoi( q );
136 if( opt.server_port < 1 || opt.server_port > 65535 )
137 goto usage;
138 }
139 else if( strcmp( p, "debug_level" ) == 0 )
140 {
141 opt.debug_level = atoi( q );
142 if( opt.debug_level < 0 || opt.debug_level > 65535 )
143 goto usage;
144 }
145 else
146 goto usage;
147 }
148
149 if( opt.mode == MODE_FILE )
150 {
151 x509_cert crt;
152
153 memset( &crt, 0, sizeof( x509_cert ) );
154
155 /*
156 * 1.1. Load the certificate
157 */
158 printf( "\n . Loading the certificate ..." );
159 fflush( stdout );
160
161 ret = x509parse_crtfile( &crt, opt.filename );
162
163 if( ret != 0 )
164 {
165 printf( " failed\n ! x509parse_crt returned %d\n\n", ret );
166 x509_free( &crt );
167 goto exit;
168 }
169
170 printf( " ok\n" );
171
172 /*
173 * 1.2 Print the certificate
174 */
175 printf( " . Peer certificate information ...\n" );
176 ret = x509parse_cert_info( (char *) buf, sizeof( buf ) - 1, " ", &crt );
177 if( ret == -1 )
178 {
179 printf( " failed\n ! x509parse_cert_info returned %d\n\n", ret );
180 x509_free( &crt );
181 goto exit;
182 }
183
184 printf( "%s\n", buf );
185
186 x509_free( &crt );
187 }
188 else if( opt.mode == MODE_SSL )
189 {
190 /*
191 * 1. Initialize the RNG and the session data
192 */
193 havege_init( &hs );
194 memset( &ssn, 0, sizeof( ssl_session ) );
195
196 /*
197 * 2. Start the connection
198 */
199 printf( " . SSL connection to tcp/%s/%-4d...", opt.server_name,
200 opt.server_port );
201 fflush( stdout );
202
203 if( ( ret = net_connect( &server_fd, opt.server_name,
204 opt.server_port ) ) != 0 )
205 {
206 printf( " failed\n ! net_connect returned %d\n\n", ret );
207 goto exit;
208 }
209
210 /*
211 * 3. Setup stuff
212 */
213 if( ( ret = ssl_init( &ssl ) ) != 0 )
214 {
215 printf( " failed\n ! ssl_init returned %d\n\n", ret );
216 goto exit;
217 }
218
219 ssl_set_endpoint( &ssl, SSL_IS_CLIENT );
220 ssl_set_authmode( &ssl, SSL_VERIFY_NONE );
221
222 ssl_set_rng( &ssl, havege_rand, &hs );
223 ssl_set_dbg( &ssl, my_debug, stdout );
224 ssl_set_bio( &ssl, net_recv, &server_fd,
225 net_send, &server_fd );
226
227 ssl_set_ciphers( &ssl, ssl_default_ciphers );
228 ssl_set_session( &ssl, 1, 600, &ssn );
229
230 ssl_set_own_cert( &ssl, &clicert, &rsa );
231
232 ssl_set_hostname( &ssl, opt.server_name );
233
234 /*
235 * 4. Handshake
236 */
237 while( ( ret = ssl_handshake( &ssl ) ) != 0 )
238 {
239 if( ret != POLARSSL_ERR_NET_TRY_AGAIN )
240 {
241 printf( " failed\n ! ssl_handshake returned %d\n\n", ret );
242 goto exit;
243 }
244 }
245
246 printf( " ok\n" );
247
248 /*
249 * 5. Print the certificate
250 */
251 printf( " . Peer certificate information ...\n" );
252 ret = x509parse_cert_info( (char *) buf, sizeof( buf ) - 1, " ", ssl.peer_cert );
253 if( ret == -1 )
254 {
255 printf( " failed\n ! x509parse_cert_info returned %d\n\n", ret );
256 goto exit;
257 }
258
259 printf( "%s\n", buf );
260
261 ssl_close_notify( &ssl );
262 }
263 else
264 goto usage;
265
266exit:
267
268 net_close( server_fd );
269 x509_free( &clicert );
270 rsa_free( &rsa );
271 ssl_free( &ssl );
272
273 memset( &ssl, 0, sizeof( ssl ) );
274
275#ifdef WIN32
276 printf( " + Press Enter to exit this program.\n" );
277 fflush( stdout ); getchar();
278#endif
279
280 return( ret );
281}