Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- 데이터베이스
- global soop
- Swift 문법
- 제앱소
- 네이버 치지직
- iOS 개발 오류
- 애플 디벨로퍼 아카데미 후기
- ObservedObject
- apple developer academy 후기
- Swift 기능
- SWIFT
- react
- Swift 디자인패턴
- ObservableObject
- 숭실대
- OS
- 소프트웨어분석및설계
- 운영체제
- 애플 디벨로퍼 아카데미
- Apple Developer Academy @ POSTECH
- 치지직
- sqoop
- 애플 아카데미 후기
- 네이버 부스트캠프
- StateObject
- 데이터베이스 공부
- 애플 디벨로퍼 아카데미 21주차 회고
- swift문법
- useReducer
- 앱 비교 프로젝트
Archives
- Today
- Total
사과하는 제라스
17. OpenSSL(TLS 서버 구축) 본문
목차
728x90
반응형
- 어떤 서버를 구축함에 있어서 인증서가 중요함.
- 인증서의 chain
사용자가 서버 인증서와 서명값을 받음 - 이 인증서의 IssuerDN인 CA1에게 감 - CA1의 IssuerDN인 RootCA에 감
- CA1 인증서에 서명된 걸 노란 키로 인증, 서버 인증서에 서명된 걸 파란 키로 인증, 초록 키 받아서 인증
- 각국의 RootCA들끼리는 peer-to-peer로 믿어줌.
- TLS 서버를 구축하려면 서버에 인증서와 개인키를 생성해야 함.
//SSL-Server.c
#include <errno.h>
#include <unistd.h>
#include <malloc.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <resolv.h>
#include "openssl/ssl.h"
#include "openssl/err.h"
#define FAIL -1
int OpenListener(int port)
{ int sd;
struct sockaddr_in addr;
sd = socket(PF_INET, SOCK_STREAM, 0);
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = INADDR_ANY;
if ( bind(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0 )
{
perror("can't bind port");
abort();
}
if ( listen(sd, 10) != 0 )
{
perror("Can't configure listening port");
abort();
}
return sd;
}
SSL_CTX* InitServerCTX(void)
{
const SSL_METHOD *method;
SSL_CTX *ctx;
OpenSSL_add_all_algorithms(); /* load & register all cryptos, etc. */
SSL_load_error_strings(); /* load all error messages */
method = TLSv1_2_server_method();
ctx = SSL_CTX_new(method); /* create new context from method */
if(ctx == NULL)
{
ERR_print_errors_fp(stderr);
abort();
}
SSL_CTX_set_cipher_list(ctx, "ALL:eNULL");
return ctx;
}
void LoadCertificates(SSL_CTX* ctx, char* CertFile, char* KeyFile)
{
//New lines
if (SSL_CTX_load_verify_locations(ctx, CertFile, KeyFile) != 1)
ERR_print_errors_fp(stderr);
if (SSL_CTX_set_default_verify_paths(ctx) != 1)
ERR_print_errors_fp(stderr);
//End new lines
/* set the local certificate from CertFile */
if (SSL_CTX_use_certificate_file(ctx, CertFile, SSL_FILETYPE_PEM) <= 0)
{
ERR_print_errors_fp(stderr);
abort();
}
/* set the private key from KeyFile (may be the same as CertFile) */
SSL_CTX_set_default_passwd_cb_userdata(ctx, "12345678");
if (SSL_CTX_use_PrivateKey_file(ctx, KeyFile, SSL_FILETYPE_PEM) <= 0)
{
ERR_print_errors_fp(stderr);
abort();
}
/* verify private key */
if (!SSL_CTX_check_private_key(ctx))
{
fprintf(stderr, "Private key does not match the public certificate\n");
abort();
}
//New lines - Force the client-side have a certificate
//SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
//SSL_CTX_set_verify_depth(ctx, 4);
//End new lines
}
void ShowCerts(SSL* ssl)
{
X509 *cert;
char *line;
cert = SSL_get_peer_certificate(ssl); /* Get certificates (if available) */
if ( cert != NULL )
{
printf("Server certificates:\n");
line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
printf("Subject: %s\n", line);
free(line);
line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
printf("Issuer: %s\n", line);
free(line);
X509_free(cert);
}
else
printf("No certificates.\n");
}
void Servlet(SSL* ssl) /* Serve the connection -- threadable */
{
char buf[1024];
int sd, bytes;
char enter[3] = { 0x0d, 0x0a, 0x00 };
char output[1024];
strcpy(output, "HTTP/1.1 200 OK");
strcat(output, enter);
strcat(output, "Content-Type: text/html");
strcat(output, enter);
strcat(output, "Content-Length: 47");
strcat(output, enter);
strcat(output, enter);
strcat(output, "<html><body><h1>Hello World!</h1></body></html>");
if ( SSL_accept(ssl) == FAIL ) /* do SSL-protocol accept */
ERR_print_errors_fp(stderr);
else
{
ShowCerts(ssl); /* get any certificates */
bytes = SSL_read(ssl, buf, sizeof(buf)); /* get request */
if ( bytes > 0 )
{
buf[bytes] = 0;
printf("Client msg: \"%s", buf);
SSL_write(ssl, output, strlen(output)); /* send reply */
}
else
ERR_print_errors_fp(stderr);
}
sd = SSL_get_fd(ssl); /* get socket connection */
SSL_free(ssl); /* release SSL state */
close(sd); /* close connection */
}
int main(int argc, char **argv)
{
SSL_CTX *ctx; // TLS 서버 구축을 위해 ctx 메모리 포인터 선언
int server;
char portnum[]="5000"; //port 번호 할당
char CertFile[] = "key/certificate.crt"; //인증성 세팅
char KeyFile[] = "key/private_key.pem"; //개인키 세팅
SSL_library_init(); //OpenSSL 라이브러리 초기화
ctx = InitServerCTX(); /* initialize SSL */
LoadCertificates(ctx, CertFile, KeyFile); /* load certs */
server = OpenListener(atoi(portnum)); /* create server socket */
while (1)
{
struct sockaddr_in addr;
socklen_t len = sizeof(addr);
SSL *ssl;
int client = accept(server, (struct sockaddr*)&addr, &len); /* accept connection as usual */
printf("Connection: %s:%d\n",inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
ssl = SSL_new(ctx); /* get new SSL state with context */
SSL_set_fd(ssl, client); /* set connection socket to SSL state */
Servlet(ssl); /* service connection */
}
close(server); /* close server socket */
SSL_CTX_free(ctx); /* release context */
}
728x90
반응형
'대학 전공 공부 > 네트워크 프로그래밍' 카테고리의 다른 글
16. Basic OpenSSL (0) | 2022.06.08 |
---|---|
15. 네트워크 보안 (0) | 2022.06.08 |
14강. 보안 기본 개념 (0) | 2022.05.21 |
13강. HTTP and Web Client (0) | 2022.05.13 |
12강. DNS (0) | 2022.05.13 |