/home/dko/projects/mobilec/trunk/src/security/xyssl-0.7/programs/ssl/ssl_server.c

Go to the documentation of this file.
00001 /* SVN FILE INFO
00002  * $Revision: 174 $ : Last Committed Revision
00003  * $Date: 2008-06-24 10:50:29 -0700 (Tue, 24 Jun 2008) $ : Last Committed Date */
00004 /*
00005  *  Basic SSL server demonstration program
00006  *
00007  *  Copyright (C) 2006-2007  Christophe Devine
00008  *
00009  *  This library is free software; you can redistribute it and/or
00010  *  modify it under the terms of the GNU Lesser General Public
00011  *  License, version 2.1 as published by the Free Software Foundation.
00012  *
00013  *  This library is distributed in the hope that it will be useful,
00014  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  *  Lesser General Public License for more details.
00017  *
00018  *  You should have received a copy of the GNU Lesser General Public
00019  *  License along with this library; if not, write to the Free Software
00020  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00021  *  MA  02110-1301  USA
00022  */
00023 
00024 #ifndef _CRT_SECURE_NO_DEPRECATE
00025 #define _CRT_SECURE_NO_DEPRECATE 1
00026 #endif
00027 
00028 #ifdef WIN32
00029 #include <windows.h>
00030 #endif
00031 
00032 #include <string.h>
00033 #include <stdio.h>
00034 
00035 #include "xyssl/havege.h"
00036 #include "xyssl/certs.h"
00037 #include "xyssl/x509.h"
00038 #include "xyssl/ssl.h"
00039 #include "xyssl/net.h"
00040 
00041 #define HTTP_RESPONSE \
00042     "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n" \
00043     "<h2><p><center>Successful connection using: %s\r\n"
00044 
00045 /*
00046  * Computing a safe DH-1024 prime takes ages, so it's faster
00047  * to use a precomputed value (provided below as an example).
00048  * Run the dh_genprime program to generate an acceptable P.
00049  */
00050 char *dhm_P = 
00051     "E4004C1F94182000103D883A448B3F80" \
00052     "2CE4B44A83301270002C20D0321CFD00" \
00053     "11CCEF784C26A400F43DFB901BCA7538" \
00054     "F2C6B176001CF5A0FD16D2C48B1D0C1C" \
00055     "F6AC8E1DA6BCC3B4E1F96B0564965300" \
00056     "FFA1D0B601EB2800F489AA512C4B248C" \
00057     "01F76949A60BB7F00A40B1EAB64BDD48" \
00058     "E8A700D60B7F1200FA8E77B0A979DABF";
00059 
00060 char *dhm_G = "4";
00061 
00062 unsigned char session_table[SSL_SESSION_TBL_LEN];
00063 
00064 /*
00065  * sorted by order of preference
00066  */
00067 int my_preferred_ciphers[] =
00068 {
00069     TLS1_EDH_RSA_AES_256_SHA,
00070     SSL3_EDH_RSA_DES_168_SHA,
00071     TLS1_RSA_AES_256_SHA,
00072     SSL3_RSA_DES_168_SHA,
00073     SSL3_RSA_RC4_128_SHA,
00074     SSL3_RSA_RC4_128_MD5,
00075     0
00076 };
00077 
00078 int main( void )
00079 {
00080     int ret, len;
00081     int listen_fd;
00082     int client_fd;
00083     unsigned char buf[1024];
00084     havege_state hs;
00085     ssl_context ssl;
00086     x509_cert srvcert;
00087     rsa_context rsa;
00088 
00089     /*
00090      * 1. Load the certificates and private RSA key
00091      */
00092     printf( "\n  . Loading the server cert. and key..." );
00093     fflush( stdout );
00094 
00095     memset( &srvcert, 0, sizeof( x509_cert ) );
00096 
00097     /*
00098      * This demonstration program uses embedded test certificates.
00099      * Instead, you may want to use x509_read_crtfile() to get the
00100      * server and CA certificates, as well as x509_read_keyfile().
00101      */
00102     ret = x509_add_certs( &srvcert, (unsigned char *) test_srv_crt,
00103                           strlen( test_srv_crt ) );
00104     if( ret != 0 )
00105     {
00106         printf( " failed\n  ! x509_add_certs returned %08x\n\n", ret );
00107         goto exit;
00108     }
00109 
00110     ret = x509_add_certs( &srvcert, (unsigned char *) test_ca_crt,
00111                           strlen( test_ca_crt ) );
00112     if( ret != 0 )
00113     {
00114         printf( " failed\n  ! x509_add_certs returned %08x\n\n", ret );
00115         goto exit;
00116     }
00117 
00118     ret = x509_parse_key( &rsa, (unsigned char *) test_srv_key,
00119                           strlen( test_srv_key ), NULL, 0 );
00120     if( ret != 0 )
00121     {
00122         printf( " failed\n  ! x509_parse_key returned %08x\n\n", ret );
00123         goto exit;
00124     }
00125 
00126     printf( " ok\n" );
00127 
00128     /*
00129      * 2. Setup the listening TCP socket
00130      */
00131     printf( "  . Bind on https://localhost:4433/ ..." );
00132     fflush( stdout );
00133 
00134     ret = net_bind( &listen_fd, NULL, 4433 );
00135     if( ret != 0 )
00136     {
00137         printf( " failed\n  ! net_bind returned %08x\n\n", ret );
00138         goto exit;
00139     }
00140 
00141     printf( " ok\n" );
00142 
00143     /*
00144      * 3. Wait until a client connects
00145      */
00146 #ifdef WIN32
00147     ShellExecute( NULL, "open", "https://localhost:4433/",
00148                   NULL, NULL, SW_SHOWNORMAL );
00149 #endif
00150 
00151     memset( &ssl, 0, sizeof( ssl ) );
00152     client_fd = -1;
00153 
00154 accept:
00155 
00156     net_close( client_fd );
00157     ssl_free( &ssl );
00158 
00159     printf( "  . Waiting for a remote connection ..." );
00160     fflush( stdout );
00161 
00162     ret = net_accept( listen_fd, &client_fd, NULL );
00163     if( ret != 0 )
00164     {
00165         printf( " failed\n  ! net_accept returned %08x\n\n", ret );
00166         goto exit;
00167     }
00168 
00169     printf( " ok\n" );
00170 
00171     /*
00172      * 4. Setup stuff
00173      */
00174     printf( "  . Setting up the RNG and SSL state..." );
00175     fflush( stdout );
00176 
00177     havege_init( &hs );
00178 
00179     if( ( ret = ssl_init( &ssl, 0 ) ) != 0 )
00180     {
00181         printf( " failed\n  ! ssl_init returned %08x\n\n", ret );
00182         goto accept;
00183     }
00184 
00185     printf( " ok\n" );
00186 
00187     ssl_set_endpoint( &ssl, SSL_IS_SERVER );
00188     ssl_set_authmode( &ssl, SSL_VERIFY_NONE );
00189 
00190     ssl_set_rng_func( &ssl, havege_rand, &hs );
00191     ssl_set_io_files( &ssl, client_fd, client_fd );
00192     ssl_set_ciphlist( &ssl, my_preferred_ciphers );
00193 
00194     ssl_set_ca_chain( &ssl, srvcert.next, NULL );
00195     ssl_set_rsa_cert( &ssl, &srvcert, &rsa );
00196 
00197     ssl_set_sidtable( &ssl, session_table );
00198     ssl_set_dhm_vals( &ssl, dhm_P, dhm_G );
00199 
00200     /*
00201      * 5. Handshake
00202      */
00203     printf( "  . Performing the SSL/TLS handshake..." );
00204     fflush( stdout );
00205 
00206     ret = ssl_server_start( &ssl );
00207     if( ret != 0 )
00208     {
00209         printf( " failed\n  ! ssl_server_start returned %08x\n\n", ret );
00210         goto accept;
00211     }
00212 
00213     printf( " ok\n" );
00214 
00215     /*
00216      * 6. Read the HTTP Request
00217      */
00218     printf( "  < Read from client:" );
00219 
00220     len = sizeof( buf ) - 1;
00221     if( ( ret = ssl_read( &ssl, buf, &len ) ) != 0 )
00222     {
00223         printf( " failed\n  ! " );
00224         switch( ret )
00225         {
00226             case ERR_SSL_PEER_CLOSE_NOTIFY:
00227                 printf( "Peer closed the connection\n\n" );
00228                 break;
00229 
00230             case ERR_NET_CONN_RESET:
00231                 printf( "Connection was reset by peer\n\n" );
00232                 break;
00233 
00234             default:
00235                 printf( "ssl_read returned %08x\n\n", ret );
00236                 break;
00237         }
00238 
00239         goto accept;
00240     }
00241 
00242     buf[len] = '\0';
00243     printf( "\n\n%s\n", buf );
00244 
00245     /*
00246      * 7. Write the 200 Response
00247      */
00248     printf( "  > Write to client:" );
00249 
00250     len = sprintf( (char *) buf, HTTP_RESPONSE,
00251                    ssl_get_cipher_name( &ssl ) );
00252 
00253     if( ( ret = ssl_write( &ssl, buf, len ) ) != 0 )
00254     {
00255         printf( " failed\n  ! ssl_write returned %08x\n\n", ret );
00256         goto accept;
00257     }
00258 
00259     printf( "\n\n%s\n", buf );
00260     ssl_close_notify( &ssl );
00261     goto accept;
00262 
00263 exit:
00264 
00265     net_close( client_fd );
00266 
00267     x509_free_cert( &srvcert );
00268     rsa_free( &rsa );
00269     ssl_free( &ssl );
00270 
00271     memset( &ssl, 0, sizeof( ssl ) );
00272 
00273 #ifdef WIN32
00274     printf( "  Press Enter to exit this program.\n" );
00275     fflush( stdout ); getchar();
00276 #endif
00277 
00278     return( ret );
00279 }

Generated on Tue Jul 1 15:29:59 2008 for Mobile-C by  doxygen 1.5.4