이건 어떻게 해야?

haesal1989의 이미지

제가 C++로 SSL을 지원하는 서버를 만들려고 하는데요..
망에 나와있는 쌤플코드들은 모두 버젼이 낮아서 그러는지 클라이언트와의 handshaking이 잘 안됩니다.
혹시 알고계시는 분들 있으면 도와주면 감사하겠습니다.
여기서 클라이언트를 인증하기 위한 인증서가 꼭 있어야 하는지 그것도 무척 궁금하네요..

int _tmain(int argc, _TCHAR* argv[])
{
	unsigned short port = PORT;
	char *serverAddress = SERVER_ADDRESS;
 
	// 서버의 소켓 타입은 TCP 같은 연결형이다.
	int socket_type = SOCK_STREAM;
	struct sockaddr_in server_add, client_add;
	int server_socket, client_socket;
 
	socket_type = SOCK_STREAM;
 
	// SSL 구조체 생성
	SSL_METHOD *meth;
	SSL_CTX *ctx;
	SSL* ssl;
 
	int retval, client_addlen;
	const char *currentCipher;
	char inbuffer[1000];
	char message[100] = "이것은 서버로부터의 응답 메시지입니다.";
 
	WSADATA wsaData;
 
	 WSAStartup(  MAKEWORD( 2, 2 ), &wsaData );
 
 
	// 화면 출력 BIO 생성
	if((errBIO = BIO_new(BIO_s_file())) != NULL)
		BIO_set_fp(errBIO, stderr, BIO_NOCLOSE|BIO_FP_TEXT);
 
	// 모든 에러 스트링 로드
	SSL_load_error_strings();
 
	// 모든 알고리즘 로드
	SSLeay_add_ssl_algorithms();
 
	// TLS 버전1 프로토콜 사용
	meth = TLSv1_server_method();
 
	// SSL 컨텍스트 생성
	ctx = SSL_CTX_new(meth);
	if(ctx == NULL) {
		BIO_printf(errBIO, "SSL_CTX 생성 에러");
		ERR_print_errors(errBIO);
		exit(1);
	}
 
	// SSL 핸드쉐이크 메시지교환 과정을 알려주는 콜백함수를 셋팅
	SSL_CTX_set_info_callback(ctx, ssl_info_callback);
 
	// 자신의 인증서를 파일에서 로딩한다.
	if(SSL_CTX_use_certificate_file(ctx, CERTF, SSL_FILETYPE_PEM) <= 0) {
		ERR_print_errors(errBIO);
		exit(1);
	}
 
	// 자신의 개인키를 파일에서 로딩한다.
	if(SSL_CTX_use_PrivateKey_file(ctx, KEYF, SSL_FILETYPE_PEM) <= 0) {
		ERR_print_errors(errBIO);
		exit(1);
	}
 
	// 읽은 인증서와 개인키가 맞는지 확인한다.
	if(!SSL_CTX_check_private_key(ctx)) {
		BIO_printf(errBIO, "인증서와 개인키가 맞지 않습니다.\n");
		ERR_print_errors(errBIO);
		exit(1);
	}
 
	// sockaddr_in 구조체의 주소체계를 인터넷 주소체계로 한다.
	server_add.sin_family = AF_INET;
 
	// 서버의 주소를 인터넷 32비트 주소로 변환하여 sockaddr_in 에 넣는다.
	server_add.sin_addr.s_addr = inet_addr(serverAddress);
 
	// 네트워크 형식으로 포트번호를 변환하여 sockaddr_in에 넣는다.
	server_add.sin_port = 47873;//htons(port);
 
	// 서버의 소켓을 생성한다.
	server_socket = socket(AF_INET, socket_type, IPPROTO_IP);    // TCP socket
	if(server_socket == -1) {
 
		int nRet = WSAGetLastError();
		fprintf(stderr, "소켓 생성 에러 \n");
		exit(1);
	}
 
	// bind를 실행하여 서버 소켓과 서버 주소를 연결한다.
	retval = bind(server_socket, (struct sockaddr*)&server_add, sizeof(server_add));
	if(retval == -1) {
		fprintf(stderr, "bind 에러!\n");
		exit(1);
	}
 
	// listen 함수를 실행하여 클라이언트가 접속할 수 있는 최대 버퍼수를 5로 정한다
	retval = listen(server_socket, 5);
	if(retval == -1) {
		fprintf(stderr, "listen 에러!\n");
		exit(1);
	}
 
	printf("주소 %s, 포트 %d 에서 클라이언트의 연결 기다림…\n", serverAddress, port);
 
 
	client_addlen = sizeof(client_add);
 
	// accept 함수를 실행 하여 클라이언트로부터의 접속을 기다린다.
	client_socket = accept(server_socket, (struct sockaddr*)&client_add, &client_addlen);
	if(client_socket == -1) {
		fprintf(stderr, "accept 에러!\n");
		exit(1);
	}
 
	// 클라이언트로부터의 접속, 연결
	printf("클라이언트 연결, 주소: %s, 포트 %d\n", inet_ntoa(client_add.sin_addr), htons(client_add.sin_port));
 
	// SSL 구조체 생성
	ssl = SSL_new(ctx);
	if(ssl == NULL) {
		BIO_printf(errBIO, "SSL 생성 에러");
		ERR_print_errors(errBIO);
		exit(1);
	}
 
	// 연결된 소켓과 SSL과의 연결
	SSL_set_fd(ssl, client_socket);
 
	// 가장 중요한 함수, 클라이언트와의 초기 협상과정, 즉 핸드쉐이크 과정을 수행
	retval = SSL_accept(ssl);
	if(retval == -1) {
		BIO_printf(errBIO, "SSL accept 에러");
		ERR_print_errors(errBIO);
		exit(1);
	}
 
	// 현재 클라이언트와 정의된 암호화 파라메터정보를 얻음
	currentCipher = SSL_CIPHER_get_name(SSL_get_current_cipher(ssl));
	printf("SSL 연결, 사용 알고리즘 파라메터 : [%s]\n", currentCipher);
 
 
	// 클라이언트로부터 SSL 통신을 통해 메시지 받음
	retval = SSL_read(ssl, inbuffer, sizeof(inbuffer) - 1);
	if(retval == -1) {
		BIO_printf(errBIO, "SSL read 에러");
		ERR_print_errors(errBIO);
		exit(1);
	}
 
	// 받은 데이터를 화면에 표시
	inbuffer[retval] = '\0';
	printf("클라이언트로부터 데이터 전송: [%s], 길이:[%d]\n", inbuffer, retval);
 
	// 클라이언트에게 SSL 통신을 통해 메시지 보냄
	retval = SSL_write(ssl, message, strlen(message));
	if(retval == -1) {
		BIO_printf(errBIO, "SSL write 에러!\n");
		ERR_print_errors(errBIO);
		exit(1);
	}
 
	// 연결 해제 및 객체 제거
	printf("연결 해제\n");
	closesocket(client_socket);
	SSL_free(ssl);
	SSL_CTX_free(ctx);
 
	Sleep(20000);
 
 
	return 0;
 
}
shint의 이미지

mongoose 서버를 사용해보세요.

----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.

각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com

불량청년의 이미지

meth = SSLv23_server_method();

위에 코드로 해보세요.

H/W가 컴퓨터의 심장이라면 S/W는 컴퓨터의 영혼이다!