PageRenderTime 41ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

/programs/ssl/ssl_server.c

https://github.com/leg0/polarssl
C | 380 lines | 257 code | 68 blank | 55 comment | 45 complexity | 2665875b0565dc6af05a0cf222b28faa MD5 | raw file
Possible License(s): GPL-2.0
  1. /*
  2. * SSL server demonstration program
  3. *
  4. * Copyright (C) 2006-2011, Brainspark B.V.
  5. *
  6. * This file is part of PolarSSL (http://www.polarssl.org)
  7. * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
  8. *
  9. * All rights reserved.
  10. *
  11. * 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. #ifndef _CRT_SECURE_NO_DEPRECATE
  26. #define _CRT_SECURE_NO_DEPRECATE 1
  27. #endif
  28. #if defined(_WIN32)
  29. #include <windows.h>
  30. #endif
  31. #include <string.h>
  32. #include <stdlib.h>
  33. #include <stdio.h>
  34. #include "polarssl/config.h"
  35. #include "polarssl/entropy.h"
  36. #include "polarssl/ctr_drbg.h"
  37. #include "polarssl/certs.h"
  38. #include "polarssl/x509.h"
  39. #include "polarssl/ssl.h"
  40. #include "polarssl/net.h"
  41. #include "polarssl/error.h"
  42. #if defined(POLARSSL_SSL_CACHE_C)
  43. #include "polarssl/ssl_cache.h"
  44. #endif
  45. #define HTTP_RESPONSE \
  46. "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n" \
  47. "<h2>PolarSSL Test Server</h2>\r\n" \
  48. "<p>Successful connection using: %s</p>\r\n"
  49. #define DEBUG_LEVEL 0
  50. void my_debug( void *ctx, int level, const char *str )
  51. {
  52. if( level < DEBUG_LEVEL )
  53. {
  54. fprintf( (FILE *) ctx, "%s", str );
  55. fflush( (FILE *) ctx );
  56. }
  57. }
  58. #if !defined(POLARSSL_BIGNUM_C) || !defined(POLARSSL_CERTS_C) || \
  59. !defined(POLARSSL_ENTROPY_C) || !defined(POLARSSL_SSL_TLS_C) || \
  60. !defined(POLARSSL_SSL_SRV_C) || !defined(POLARSSL_NET_C) || \
  61. !defined(POLARSSL_RSA_C) || !defined(POLARSSL_CTR_DRBG_C)
  62. int main( int argc, char *argv[] )
  63. {
  64. ((void) argc);
  65. ((void) argv);
  66. printf("POLARSSL_BIGNUM_C and/or POLARSSL_CERTS_C and/or POLARSSL_ENTROPY_C "
  67. "and/or POLARSSL_SSL_TLS_C and/or POLARSSL_SSL_SRV_C and/or "
  68. "POLARSSL_NET_C and/or POLARSSL_RSA_C and/or "
  69. "POLARSSL_CTR_DRBG_C not defined.\n");
  70. return( 0 );
  71. }
  72. #else
  73. int main( int argc, char *argv[] )
  74. {
  75. int ret, len;
  76. int listen_fd;
  77. int client_fd = -1;
  78. unsigned char buf[1024];
  79. char *pers = "ssl_server";
  80. entropy_context entropy;
  81. ctr_drbg_context ctr_drbg;
  82. ssl_context ssl;
  83. x509_cert srvcert;
  84. rsa_context rsa;
  85. #if defined(POLARSSL_SSL_CACHE_C)
  86. ssl_cache_context cache;
  87. #endif
  88. ((void) argc);
  89. ((void) argv);
  90. #if defined(POLARSSL_SSL_CACHE_C)
  91. ssl_cache_init( &cache );
  92. #endif
  93. /*
  94. * 1. Load the certificates and private RSA key
  95. */
  96. printf( "\n . Loading the server cert. and key..." );
  97. fflush( stdout );
  98. memset( &srvcert, 0, sizeof( x509_cert ) );
  99. /*
  100. * This demonstration program uses embedded test certificates.
  101. * Instead, you may want to use x509parse_crtfile() to read the
  102. * server and CA certificates, as well as x509parse_keyfile().
  103. */
  104. ret = x509parse_crt( &srvcert, (unsigned char *) test_srv_crt,
  105. strlen( test_srv_crt ) );
  106. if( ret != 0 )
  107. {
  108. printf( " failed\n ! x509parse_crt returned %d\n\n", ret );
  109. goto exit;
  110. }
  111. ret = x509parse_crt( &srvcert, (unsigned char *) test_ca_crt,
  112. strlen( test_ca_crt ) );
  113. if( ret != 0 )
  114. {
  115. printf( " failed\n ! x509parse_crt returned %d\n\n", ret );
  116. goto exit;
  117. }
  118. rsa_init( &rsa, RSA_PKCS_V15, 0 );
  119. ret = x509parse_key( &rsa, (unsigned char *) test_srv_key,
  120. strlen( test_srv_key ), NULL, 0 );
  121. if( ret != 0 )
  122. {
  123. printf( " failed\n ! x509parse_key returned %d\n\n", ret );
  124. goto exit;
  125. }
  126. printf( " ok\n" );
  127. /*
  128. * 2. Setup the listening TCP socket
  129. */
  130. printf( " . Bind on https://localhost:4433/ ..." );
  131. fflush( stdout );
  132. if( ( ret = net_bind( &listen_fd, NULL, 4433 ) ) != 0 )
  133. {
  134. printf( " failed\n ! net_bind returned %d\n\n", ret );
  135. goto exit;
  136. }
  137. printf( " ok\n" );
  138. /*
  139. * 3. Seed the RNG
  140. */
  141. printf( " . Seeding the random number generator..." );
  142. fflush( stdout );
  143. entropy_init( &entropy );
  144. if( ( ret = ctr_drbg_init( &ctr_drbg, entropy_func, &entropy,
  145. (unsigned char *) pers, strlen( pers ) ) ) != 0 )
  146. {
  147. printf( " failed\n ! ctr_drbg_init returned %d\n", ret );
  148. goto exit;
  149. }
  150. printf( " ok\n" );
  151. /*
  152. * 4. Setup stuff
  153. */
  154. printf( " . Setting up the SSL data...." );
  155. fflush( stdout );
  156. if( ( ret = ssl_init( &ssl ) ) != 0 )
  157. {
  158. printf( " failed\n ! ssl_init returned %d\n\n", ret );
  159. goto exit;
  160. }
  161. ssl_set_endpoint( &ssl, SSL_IS_SERVER );
  162. ssl_set_authmode( &ssl, SSL_VERIFY_NONE );
  163. ssl_set_rng( &ssl, ctr_drbg_random, &ctr_drbg );
  164. ssl_set_dbg( &ssl, my_debug, stdout );
  165. #if defined(POLARSSL_SSL_CACHE_C)
  166. ssl_set_session_cache( &ssl, ssl_cache_get, &cache,
  167. ssl_cache_set, &cache );
  168. #endif
  169. ssl_set_ca_chain( &ssl, srvcert.next, NULL, NULL );
  170. ssl_set_own_cert( &ssl, &srvcert, &rsa );
  171. printf( " ok\n" );
  172. reset:
  173. #ifdef POLARSSL_ERROR_C
  174. if( ret != 0 )
  175. {
  176. char error_buf[100];
  177. error_strerror( ret, error_buf, 100 );
  178. printf("Last error was: %d - %s\n\n", ret, error_buf );
  179. }
  180. #endif
  181. if( client_fd != -1 )
  182. net_close( client_fd );
  183. ssl_session_reset( &ssl );
  184. /*
  185. * 3. Wait until a client connects
  186. */
  187. #if defined(_WIN32_WCE)
  188. {
  189. SHELLEXECUTEINFO sei;
  190. ZeroMemory( &sei, sizeof( SHELLEXECUTEINFO ) );
  191. sei.cbSize = sizeof( SHELLEXECUTEINFO );
  192. sei.fMask = 0;
  193. sei.hwnd = 0;
  194. sei.lpVerb = _T( "open" );
  195. sei.lpFile = _T( "https://localhost:4433/" );
  196. sei.lpParameters = NULL;
  197. sei.lpDirectory = NULL;
  198. sei.nShow = SW_SHOWNORMAL;
  199. ShellExecuteEx( &sei );
  200. }
  201. #elif defined(_WIN32)
  202. ShellExecute( NULL, "open", "https://localhost:4433/",
  203. NULL, NULL, SW_SHOWNORMAL );
  204. #endif
  205. client_fd = -1;
  206. printf( " . Waiting for a remote connection ..." );
  207. fflush( stdout );
  208. if( ( ret = net_accept( listen_fd, &client_fd, NULL ) ) != 0 )
  209. {
  210. printf( " failed\n ! net_accept returned %d\n\n", ret );
  211. goto exit;
  212. }
  213. ssl_set_bio( &ssl, net_recv, &client_fd,
  214. net_send, &client_fd );
  215. printf( " ok\n" );
  216. /*
  217. * 5. Handshake
  218. */
  219. printf( " . Performing the SSL/TLS handshake..." );
  220. fflush( stdout );
  221. while( ( ret = ssl_handshake( &ssl ) ) != 0 )
  222. {
  223. if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE )
  224. {
  225. printf( " failed\n ! ssl_handshake returned %d\n\n", ret );
  226. goto reset;
  227. }
  228. }
  229. printf( " ok\n" );
  230. /*
  231. * 6. Read the HTTP Request
  232. */
  233. printf( " < Read from client:" );
  234. fflush( stdout );
  235. do
  236. {
  237. len = sizeof( buf ) - 1;
  238. memset( buf, 0, sizeof( buf ) );
  239. ret = ssl_read( &ssl, buf, len );
  240. if( ret == POLARSSL_ERR_NET_WANT_READ || ret == POLARSSL_ERR_NET_WANT_WRITE )
  241. continue;
  242. if( ret <= 0 )
  243. {
  244. switch( ret )
  245. {
  246. case POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY:
  247. printf( " connection was closed gracefully\n" );
  248. break;
  249. case POLARSSL_ERR_NET_CONN_RESET:
  250. printf( " connection was reset by peer\n" );
  251. break;
  252. default:
  253. printf( " ssl_read returned -0x%x\n", -ret );
  254. break;
  255. }
  256. break;
  257. }
  258. len = ret;
  259. printf( " %d bytes read\n\n%s", len, (char *) buf );
  260. if( ret > 0 )
  261. break;
  262. }
  263. while( 1 );
  264. /*
  265. * 7. Write the 200 Response
  266. */
  267. printf( " > Write to client:" );
  268. fflush( stdout );
  269. len = sprintf( (char *) buf, HTTP_RESPONSE,
  270. ssl_get_ciphersuite( &ssl ) );
  271. while( ( ret = ssl_write( &ssl, buf, len ) ) <= 0 )
  272. {
  273. if( ret == POLARSSL_ERR_NET_CONN_RESET )
  274. {
  275. printf( " failed\n ! peer closed the connection\n\n" );
  276. goto reset;
  277. }
  278. if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE )
  279. {
  280. printf( " failed\n ! ssl_write returned %d\n\n", ret );
  281. goto exit;
  282. }
  283. }
  284. len = ret;
  285. printf( " %d bytes written\n\n%s\n", len, (char *) buf );
  286. ret = 0;
  287. goto reset;
  288. exit:
  289. #ifdef POLARSSL_ERROR_C
  290. if( ret != 0 )
  291. {
  292. char error_buf[100];
  293. error_strerror( ret, error_buf, 100 );
  294. printf("Last error was: %d - %s\n\n", ret, error_buf );
  295. }
  296. #endif
  297. net_close( client_fd );
  298. x509_free( &srvcert );
  299. rsa_free( &rsa );
  300. ssl_free( &ssl );
  301. #if defined(POLARSSL_SSL_CACHE_C)
  302. ssl_cache_free( &cache );
  303. #endif
  304. #if defined(_WIN32)
  305. printf( " Press Enter to exit this program.\n" );
  306. fflush( stdout ); getchar();
  307. #endif
  308. return( ret );
  309. }
  310. #endif /* POLARSSL_BIGNUM_C && POLARSSL_CERTS_C && POLARSSL_ENTROPY_C &&
  311. POLARSSL_SSL_TLS_C && POLARSSL_SSL_SRV_C && POLARSSL_NET_C &&
  312. POLARSSL_RSA_C && POLARSSL_CTR_DRBG_C */