root/src/router/wgets/wgets.c

Revision 11401, 5.4 kB (checked in by BrainSlayer, 10 months ago)

https client

Line 
1 /*
2  *  SSL client with certificate authentication
3  *
4  *  Copyright (C) 2006-2007  Christophe Devine
5  *
6  *  This library is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU Lesser General Public
8  *  License, version 2.1 as published by the Free Software Foundation.
9  *
10  *  This library is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  *  Lesser General Public License for more details.
14  *
15  *  You should have received a copy of the GNU Lesser General Public
16  *  License along with this library; if not, write to the Free Software
17  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18  *  MA  02110-1301  USA
19  */
20
21 #ifndef _CRT_SECURE_NO_DEPRECATE
22 #define _CRT_SECURE_NO_DEPRECATE 1
23 #endif
24
25 #include <string.h>
26 #include <stdio.h>
27
28 #include "xyssl/net.h"
29 #include "xyssl/ssl.h"
30 #include "xyssl/havege.h"
31 #include "xyssl/certs.h"
32 #include "xyssl/x509.h"
33
34 #define SERVER_PORT 443
35
36 #define DEBUG_LEVEL 0
37
38 void my_debug( void *ctx, int level, char *str )
39 {
40     if( level < DEBUG_LEVEL )
41     {
42         fprintf( ( FILE * ) ctx, "%s", str );
43         fflush( ( FILE * ) ctx );
44     }
45 }
46
47 int main( int argc, char *argv[] )
48 {
49     int ret, len, server_fd;
50     unsigned char buf[2];
51     havege_state hs;
52     ssl_context ssl;
53     ssl_session ssn;
54     x509_cert cacert;
55     x509_cert clicert;
56     rsa_context rsa;
57
58     char *SERVER_NAME = argv[1];
59     char GET_REQUEST[128];
60
61     sprintf( GET_REQUEST, "GET %s HTTP/1.1\r\nHost: %s\r\n\r\n", argv[2],
62              argv[1] );
63
64     /*
65      * 0. Initialize the RNG and the session data
66      */
67     havege_init( &hs );
68     memset( &ssn, 0, sizeof( ssl_session ) );
69
70     memset( &cacert, 0, sizeof( x509_cert ) );
71
72     /*
73      * Alternatively, you may load the CA certificates from a .pem or
74      * .crt file by calling x509parse_crtfile( &cacert, "myca.crt" ).
75      */
76     ret = x509parse_crt( &cacert, ( unsigned char * )xyssl_ca_crt,
77                          strlen( xyssl_ca_crt ) );
78     if( ret != 0 )
79     {
80         printf( " failed\n  !  x509parse_crt returned %d\n\n", ret );
81         goto exit;
82     }
83
84     /*
85      * 1.2. Load own certificate and private key
86      *
87      * (can be skipped if client authentication is not required)
88      */
89
90     memset( &clicert, 0, sizeof( x509_cert ) );
91
92     ret = x509parse_crt( &clicert, ( unsigned char * )test_cli_crt,
93                          strlen( test_cli_crt ) );
94     if( ret != 0 )
95     {
96         printf( " failed\n  !  x509parse_crt returned %d\n\n", ret );
97         goto exit;
98     }
99
100     ret = x509parse_key( &rsa, ( unsigned char * )test_cli_key,
101                          strlen( test_cli_key ), NULL, 0 );
102     if( ret != 0 )
103     {
104         printf( " failed\n  !  x509parse_key returned %d\n\n", ret );
105         goto exit;
106     }
107
108     if( ( ret = net_connect( &server_fd, SERVER_NAME, SERVER_PORT ) ) != 0 )
109     {
110         printf( " failed\n  ! net_connect returned %d\n\n", ret );
111         goto exit;
112     }
113
114     havege_init( &hs );
115
116     if( ( ret = ssl_init( &ssl ) ) != 0 )
117     {
118         printf( " failed\n  ! ssl_init returned %d\n\n", ret );
119         goto exit;
120     }
121
122     ssl_set_endpoint( &ssl, SSL_IS_CLIENT );
123     ssl_set_authmode( &ssl, SSL_VERIFY_OPTIONAL );
124
125     ssl_set_rng( &ssl, havege_rand, &hs );
126     ssl_set_bio( &ssl, net_recv, &server_fd, net_send, &server_fd );
127
128     ssl_set_ciphers( &ssl, ssl_default_ciphers );
129     ssl_set_session( &ssl, 1, 600, &ssn );
130
131     ssl_set_ca_chain( &ssl, &cacert, SERVER_NAME );
132     ssl_set_own_cert( &ssl, &clicert, &rsa );
133
134     ssl_set_hostname( &ssl, SERVER_NAME );
135
136     while( ( ret = ssl_handshake( &ssl ) ) != 0 )
137     {
138         if( ret != XYSSL_ERR_NET_TRY_AGAIN )
139         {
140             printf( " failed\n  ! ssl_handshake returned %d\n\n", ret );
141             goto exit;
142         }
143     }
144
145     if( ( ret = ssl_get_verify_result( &ssl ) ) != 0 )
146     {
147         printf( "certificate check failed\n" );
148
149         if( ( ret & BADCERT_EXPIRED ) != 0 )
150             printf( "  ! server certificate has expired\n" );
151
152         if( ( ret & BADCERT_REVOKED ) != 0 )
153             printf( "  ! server certificate has been revoked\n" );
154
155         if( ( ret & BADCERT_CN_MISMATCH ) != 0 )
156             printf( "  ! CN mismatch (expected CN=%s)\n", SERVER_NAME );
157
158         if( ( ret & BADCERT_NOT_TRUSTED ) != 0 )
159             printf( "  ! self-signed or not signed by a trusted CA\n" );
160
161         printf( "\n" );
162     }
163
164     len = sprintf( ( char * )buf, GET_REQUEST );
165
166     while( ( ret = ssl_write( &ssl, buf, len ) ) <= 0 )
167     {
168         if( ret != XYSSL_ERR_NET_TRY_AGAIN )
169         {
170             printf( " failed\n  ! ssl_write returned %d\n\n", ret );
171             goto exit;
172         }
173     }
174
175     len = ret;
176
177     /*
178      * 7. Read the HTTP response
179      */
180     fflush( stdout );
181     FILE *out = fopen( argv[3], "wb" );
182     int found = 0;
183     int offset = 0;
184
185     do
186     {
187         offset = 0;
188         len = sizeof( buf ) - 1;
189         memset( buf, 0, sizeof( buf ) );
190         ret = ssl_read( &ssl, buf, len );
191
192         if( ret == XYSSL_ERR_NET_TRY_AGAIN )
193             continue;
194
195         if( ret == XYSSL_ERR_SSL_PEER_CLOSE_NOTIFY )
196             break;
197
198         if( ret <= 0 )
199         {
200             printf( "failed\n  ! ssl_read returned %d\n\n", ret );
201             break;
202         }
203         if( found < 4 )
204         {
205             if( found == 0 || found == 2 )
206                 if( buf[0] == '\r' )
207                 {
208                     found++;
209                     continue;
210                 }
211                 else
212                     found = 0;
213             if( found == 1 || found == 3 )
214                 if( buf[0] == '\n' )
215                 {
216                     found++;
217                     continue;
218                 }
219                 else
220                     found = 0;
221         }
222         else
223             putc( buf[0], out );
224         len = ret;
225     }
226     while( 1 );
227
228     ssl_close_notify( &ssl );
229
230   exit:
231     fclose( out );
232
233     net_close( server_fd );
234     x509_free( &clicert );
235     x509_free( &cacert );
236     rsa_free( &rsa );
237     ssl_free( &ssl );
238
239     memset( &ssl, 0, sizeof( ssl ) );
240
241     return ( ret );
242 }
Note: See TracBrowser for help on using the browser.