サーバ編
サーバも基本的には同じで、acceptしたあとSSL構造体を作ってSSL_set_fdしてSSL_acceptしてあげればOKです。
// SSL_CTXを作るところまではクライアントと同じ
// TLSv1_client_method()等のかわりにTLSv1_server_method()などを用いる
SSL_load_error_strings();
SSL_library_init();
if(!(ctx=SSL_CTX_new(TLSv1_server_method())))
{
fprintf(stderr,"SSL init error.\n");
ERR_free_strings();
return -1;
};
// 秘密鍵KEYFILEを読み込み
// SSL_FILETYPE_PEMは通常のBase64でテキスト化された鍵ファイルの場合
SSL_CTX_use_PrivateKey_file(ctx,KEYFILE,SSL_FILETYPE_PEM);
// 証明書CRTFILEを読み込み
SSL_CTX_use_certificate_file(ctx,CRTFILE,SSL_FILETYPE_PEM);
// ソケット生成
int sock,sock_accept;
struct addrinfo hints,*ai,*ai_start;
memset(&hints,0,sizeof(hints));
hints.ai_family=protocol;
hints.ai_socktype=SOCK_STREAM;
hints.ai_flags=AI_PASSIVE;
if(getaddrinfo(NULL,temp,&hints,&ai_start))
{
fprintf(stderr,"getaddrinfo error\n");
SSL_CTX_free(ctx);
ERR_free_strings();
return -1;
};
sock=-1;
for(ai=ai_start;ai!=NULL;ai=ai->ai_next)
{
sock=socket(ai->ai_family,ai->ai_socktype,ai->ai_protocol);
if(sock<0){continue;};
if(bind(sock,ai->ai_addr,(int)ai->ai_addrlen)<0)
{
close(sock);
sock=-1;
continue;
};
if(listen(sock,5)<0)
{
close(sock);
sock=-1;
continue;
};
};
freeaddrinfo(ai_start);
if(sock<0)
{
fprintf(stderr,"Can't create socket\n");
SSL_CTX_free(ctx);
ERR_free_strings();
return -1;
};
// acceptしたらforkしてSSL_accept
sock_accept=-1;
struct sockaddr fromadd;
int fromlen=sizeof(fromadd);
while(1)
{
sock_accept=accept(sock,(struct sockaddr*)&fromadd,&fromlen);
if(sock_accept==-1){continue;};
if(0==fork())
{
// child process
if(!(ssl=SSL_new(ctx)) || !SSL_set_fd(ssl,sock_accept))
{
fprintf(stderr,"Can't crate SSL object.\n");
if(ssl){SSL_free(ssl);};
SSL_CTX_free(ctx);
ERR_free_strings();
return -1;
};
if(SSL_accept(ssl)>=0)
{
// サーバとしての処理を行う
SSL_shutdown(ssl);
};
SSL_free(ssl);
close(sock_accept);
fprintf(stderr,"closed\n");
SSL_CTX_free(ctx);
ERR_free_strings();
return 0;
}else{
// parent process
close(sock_accept);
};
};
2008-07-12 13:19:11[プログラミング]
この記事へのトラックバックURL: https://www.asmusic.jp/ASHARD/score/tb.cgi/yu-oishi/20080710_3
手動トラックバック