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

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

Generated on Fri May 16 14:49:55 2008 for Mobile-C by  doxygen 1.5.4