// OpenSSL で暗号化した TCP/IP 通信プログラムの雛型 (サーバー側)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <openssl/ssl.h>
#include "integnet.h"

// 接続のポート
#define PORT 12345

int main( void )
{
  // INET で STREAM なソケットの作成
  int sb = socket( AF_INET, SOCK_STREAM, 0 );

  // 接続の目印の指定
  sockaddr_in addr = SOCKADDR_IN_INIT( AF_INET, htons(PORT), InAddr(htonl(INADDR_ANY)) );

  // 目印の公開
  if( bind( sb, (sockaddr*)&addr, sizeof(addr) ) < 0 ){
    perror("bind");
    exit(1);
  }

  // 接続要求の受信開始(同時に1回線まで接続可とする)
  listen( sb, 1 );

  // 接続要求の受信
  int s = accept( sb, NULL, NULL );

  // SSLの初期化
  SSL_library_init(); 
  SSL_CTX* ctx = SSL_CTX_new( SSLv2_server_method() ); 
  SSL* ssl = SSL_new( ctx );
  SSL_set_fd( ssl, s );

  // SSLの公開鍵と秘密鍵の読みだし
  SSL_use_certificate_file( ssl, "public.key", SSL_FILETYPE_PEM );
  SSL_use_PrivateKey_file( ssl, "private.key", SSL_FILETYPE_PEM );

  // SSL通信の開始
  SSL_accept(ssl);

  char msg[64];
  int len;
  len = SSL_read( ssl, msg, sizeof(msg) );
  msg[len] = '\0';

  printf("Server received : %s\n", msg );
  
  // SSLの終了
  SSL_shutdown(ssl); 
  SSL_free(ssl); 
  SSL_CTX_free(ctx);

  // ソケットの廃止
  close(s);
  close(sb);

  return 0;
}