server.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <sys/socket.h>
  4. #include <arpa/inet.h>
  5. #include <openssl/ssl.h>
  6. #include <openssl/err.h>
  7. int create_socket(int port)
  8. {
  9. int s;
  10. struct sockaddr_in addr;
  11. addr.sin_family = AF_INET;
  12. addr.sin_port = htons(port);
  13. addr.sin_addr.s_addr = htonl(INADDR_ANY);
  14. s = socket(AF_INET, SOCK_STREAM, 0);
  15. if (s < 0) {
  16. perror("Unable to create socket");
  17. exit(EXIT_FAILURE);
  18. }
  19. if (bind(s, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
  20. perror("Unable to bind");
  21. exit(EXIT_FAILURE);
  22. }
  23. if (listen(s, 1) < 0) {
  24. perror("Unable to listen");
  25. exit(EXIT_FAILURE);
  26. }
  27. return s;
  28. }
  29. void init_openssl()
  30. {
  31. SSL_load_error_strings();
  32. OpenSSL_add_ssl_algorithms();
  33. }
  34. void cleanup_openssl()
  35. {
  36. EVP_cleanup();
  37. }
  38. SSL_CTX *create_context()
  39. {
  40. const SSL_METHOD *method;
  41. SSL_CTX *ctx;
  42. method = TLSv1_2_server_method();
  43. ctx = SSL_CTX_new(method);
  44. if (!ctx) {
  45. perror("Unable to create SSL context");
  46. ERR_print_errors_fp(stderr);
  47. exit(EXIT_FAILURE);
  48. }
  49. return ctx;
  50. }
  51. void configure_context(SSL_CTX *ctx)
  52. {
  53. SSL_CTX_set_ecdh_auto(ctx, 1);
  54. /* Set the key and cert */
  55. if (SSL_CTX_use_certificate_file(ctx, "domain.crt", SSL_FILETYPE_PEM) < 0) {
  56. ERR_print_errors_fp(stderr);
  57. exit(EXIT_FAILURE);
  58. }
  59. if (SSL_CTX_use_PrivateKey_file(ctx, "domain.key", SSL_FILETYPE_PEM) < 0 ) {
  60. ERR_print_errors_fp(stderr);
  61. exit(EXIT_FAILURE);
  62. }
  63. SSL_CTX_set_cipher_list(ctx, "ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384");
  64. }
  65. int main(int argc, char **argv)
  66. {
  67. int sock;
  68. SSL_CTX *ctx;
  69. init_openssl();
  70. ctx = create_context();
  71. configure_context(ctx);
  72. sock = create_socket(8888);
  73. /* Handle connections */
  74. while(1) {
  75. struct sockaddr_in addr;
  76. uint len = sizeof(addr);
  77. SSL *ssl;
  78. const char reply[] = "test\n";
  79. int client = accept(sock, (struct sockaddr*)&addr, &len);
  80. if (client < 0) {
  81. perror("Unable to accept");
  82. exit(EXIT_FAILURE);
  83. }
  84. ssl = SSL_new(ctx);
  85. SSL_set_fd(ssl, client);
  86. if (SSL_accept(ssl) <= 0) {
  87. ERR_print_errors_fp(stderr);
  88. }
  89. else {
  90. SSL_write(ssl, reply, strlen(reply));
  91. }
  92. SSL_free(ssl);
  93. close(client);
  94. }
  95. close(sock);
  96. SSL_CTX_free(ctx);
  97. cleanup_openssl();
  98. }