00001 /* 00002 * SSL client demonstration program 00003 * 00004 * Copyright (C) 2006-2007 Christophe Devine 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License along 00017 * with this program; if not, write to the Free Software Foundation, Inc., 00018 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00019 */ 00020 00021 #ifndef _CRT_SECURE_NO_DEPRECATE 00022 #define _CRT_SECURE_NO_DEPRECATE 1 00023 #endif 00024 00025 #include <string.h> 00026 #include <stdio.h> 00027 00028 #include "xyssl/net.h" 00029 #include "xyssl/ssl.h" 00030 #include "xyssl/havege.h" 00031 00032 #define SERVER_PORT 443 00033 /* 00034 #define SERVER_NAME "localhost" 00035 #define GET_REQUEST "GET / HTTP/1.0\r\n\r\n" 00036 */ 00037 #define SERVER_NAME "xyssl.org" 00038 #define GET_REQUEST \ 00039 "GET /hello/ HTTP/1.1\r\n" \ 00040 "Host: xyssl.org\r\n\r\n" 00041 00042 #define DEBUG_LEVEL 0 00043 00044 void my_debug( void *ctx, int level, char *str ) 00045 { 00046 if( level < DEBUG_LEVEL ) 00047 { 00048 fprintf( (FILE *) ctx, "%s", str ); 00049 fflush( (FILE *) ctx ); 00050 } 00051 } 00052 00053 int main( void ) 00054 { 00055 int ret, len, server_fd; 00056 unsigned char buf[1024]; 00057 havege_state hs; 00058 ssl_context ssl; 00059 ssl_session ssn; 00060 00061 /* 00062 * 0. Initialize the RNG and the session data 00063 */ 00064 havege_init( &hs ); 00065 memset( &ssn, 0, sizeof( ssl_session ) ); 00066 00067 /* 00068 * 1. Start the connection 00069 */ 00070 printf( "\n . Connecting to tcp/%s/%4d...", SERVER_NAME, 00071 SERVER_PORT ); 00072 fflush( stdout ); 00073 00074 if( ( ret = net_connect( &server_fd, SERVER_NAME, 00075 SERVER_PORT ) ) != 0 ) 00076 { 00077 printf( " failed\n ! net_connect returned %d\n\n", ret ); 00078 goto exit; 00079 } 00080 00081 printf( " ok\n" ); 00082 00083 /* 00084 * 2. Setup stuff 00085 */ 00086 printf( " . Setting up the SSL/TLS structure..." ); 00087 fflush( stdout ); 00088 00089 if( ( ret = ssl_init( &ssl ) ) != 0 ) 00090 { 00091 printf( " failed\n ! ssl_init returned %d\n\n", ret ); 00092 goto exit; 00093 } 00094 00095 printf( " ok\n" ); 00096 00097 ssl_set_endpoint( &ssl, SSL_IS_CLIENT ); 00098 ssl_set_authmode( &ssl, SSL_VERIFY_NONE ); 00099 00100 ssl_set_rng( &ssl, havege_rand, &hs ); 00101 ssl_set_dbg( &ssl, my_debug, stdout ); 00102 ssl_set_bio( &ssl, net_recv, &server_fd, 00103 net_send, &server_fd ); 00104 00105 ssl_set_ciphers( &ssl, ssl_default_ciphers ); 00106 ssl_set_session( &ssl, 1, 600, &ssn ); 00107 00108 /* 00109 * 3. Write the GET request 00110 */ 00111 printf( " > Write to server:" ); 00112 fflush( stdout ); 00113 00114 len = sprintf( (char *) buf, GET_REQUEST ); 00115 00116 while( ( ret = ssl_write( &ssl, buf, len ) ) <= 0 ) 00117 { 00118 if( ret != XYSSL_ERR_NET_TRY_AGAIN ) 00119 { 00120 printf( " failed\n ! ssl_write returned %d\n\n", ret ); 00121 goto exit; 00122 } 00123 } 00124 00125 len = ret; 00126 printf( " %d bytes written\n\n%s", len, (char *) buf ); 00127 00128 /* 00129 * 7. Read the HTTP response 00130 */ 00131 printf( " < Read from server:" ); 00132 fflush( stdout ); 00133 00134 do 00135 { 00136 len = sizeof( buf ) - 1; 00137 memset( buf, 0, sizeof( buf ) ); 00138 ret = ssl_read( &ssl, buf, len ); 00139 00140 if( ret == XYSSL_ERR_NET_TRY_AGAIN ) 00141 continue; 00142 00143 if( ret == XYSSL_ERR_SSL_PEER_CLOSE_NOTIFY ) 00144 break; 00145 00146 if( ret <= 0 ) 00147 { 00148 printf( "failed\n ! ssl_read returned %d\n\n", ret ); 00149 break; 00150 } 00151 00152 len = ret; 00153 printf( " %d bytes read\n\n%s", len, (char *) buf ); 00154 } 00155 while( 0 ); 00156 00157 ssl_close_notify( &ssl ); 00158 00159 exit: 00160 00161 net_close( server_fd ); 00162 ssl_free( &ssl ); 00163 00164 memset( &ssl, 0, sizeof( ssl ) ); 00165 00166 #ifdef WIN32 00167 printf( " + Press Enter to exit this program.\n" ); 00168 fflush( stdout ); getchar(); 00169 #endif 00170 00171 return( ret ); 00172 }