2012-04-17 3 views
2

openSSL API를 사용하여 SSL 핸드 셰이크를 수행하는 클라이언트 및 서버 코드를 작성하려고합니다.openSSL : 핸드 셰이크 실패 - 서버가 클라이언트 인증서를 얻을 수 없음

클라이언트 코드가 포함되어

// Part of client code: 
SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,NULL); 
SSL_CTX_load_verify_locations(ctx,"ca.pem",NULL); 
... 
if (SSL_CTX_use_certificate_file(ctx, "cli.crt" , SSL_FILETYPE_PEM) <= 0) { 
    exit(1); 
    } 

    if (SSL_CTX_use_PrivateKey_file(ctx, "cli.key", SSL_FILETYPE_PEM) <= 0) { 
    exit(1); 
    } 
... 
sd = socket (AF_INET, SOCK_STREAM, 0); 
sa.sin_family  = AF_INET; 
sa.sin_addr.s_addr = inet_addr ("127.0.0.1"); 
sa.sin_port  = htons (44444); 
... 
ssl = SSL_new (ctx);    
SSL_set_fd (ssl, sd); 
err = SSL_connect (ssl); 

서버 코드가 포함되어 코드에서 볼 수 있듯이 나는, 루프백 주소 (127.0.0.1)로 목적지 주소를 사용하여 코드를 실행

// Part of server code: 
SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,NULL); 
SSL_CTX_load_verify_locations(ctx,"ca.pem",NULL); 
... 
if (SSL_CTX_use_certificate_file(ctx, "serv.crt", SSL_FILETYPE_PEM) <= 0) { 
    exit(1); 
} 
if (SSL_CTX_use_PrivateKey_file(ctx, "serv.key", SSL_FILETYPE_PEM) <= 0) { 
    exit(1); 
    } 
... 
listen_sd = socket (AF_INET, SOCK_STREAM, 0); 
memset (&sa_serv, '\0', sizeof(sa_serv)); 
sa_serv.sin_family  = AF_INET; 
sa_serv.sin_addr.s_addr = INADDR_ANY; 
sa_serv.sin_port  = htons (44444); 

err = bind(listen_sd, (struct sockaddr*) &sa_serv, sizeof (sa_serv));       
err = listen (listen_sd, 5);  
client_len = sizeof(sa_cli); 
sd = accept (listen_sd, (struct sockaddr*) &sa_cli, &client_len); 
close (listen_sd); 
.... 
ssl = SSL_new (ctx);       
SSL_set_fd (ssl, sd); 
err = SSL_accept (ssl); 

위에 표시된. 동일한 컴퓨터에서 실행되는 클라이언트 및 서버 프로그램이 정상적으로 작동했습니다.

하지만 다른 컴퓨터 (VMWare VM - Ubuntu Linux)에서 클라이언트 및 서버 프로그램을 실행하면 코드가 실패합니다. 클라이언트 코드의 주소로 서버의 IP VM (예 : 192.168.181.180)를 사용하여

Client VM IP:192.168.181.188 
Server VM IP:192.168.181.180 

, 나는 서버에서 다음과 같은 오류를 얻을 : 내 리눅스 시스템에서 내 자신의 CA를 만든

140890B2: SSL3_GET_CLIENT_CERTIFICATE:no certificate returned: s3_srvr.c:2602: 

CA 공개 키 파일을 클라이언트 및 서버 VM과 공유했습니다. 클라이언트 및 서버 인증서는이 CA에서 서명합니다.

CA : CA123 
Client CN: Client (signed by CA123) 
Server CN: Server (signed by CA123) 

클라이언트는 (심지어 서버 인증서를 얻을 CN은 '서버'참으로 확인하실 수 있습니다)하지만, 서버가 클라이언트 인증서를 얻을 수없는, 그래서 핸드 셰이크가 실패 서버 인증서를 확인 할 수 있습니다.

누구든지이 문제에 대한 해결책을 제안 할 수 있습니까?

고마워요.

답변

0

클라이언트 인증서의 subject을 확인하십시오. CN (일반 이름) 필드에 클라이언트 호스트의 IP 또는 호스트 이름이 있어야하는 경우가 있습니다.

Subject: C=xxx, ST=xxx, L=xxx, O=xxx, OU=xxx, CN=192.168.181.180 

나는이 수정 프로그램에 대한 확실하지 않은 100 %입니다 : 귀하의 경우

는 클라이언트 인증서는 다음과 같은 주제를 가질 수있다. 그러나 벽을 부수기 전에 그것을 시도하십시오.

+0

나는 IP가 아닌 CN을 검사했다. 내 Linux 컴퓨터에서 자체 CA를 만들고 해당 CA로 내 서버 및 클라이언트 인증서에 서명했습니다. 클라이언트 CN은 "클라이언트"이고 서버 CN은 "서버"입니다. CA는 "CA123"입니다. – Jake

0

좋아요 ... 다음은 완벽한 솔루션이며, 현재 프로젝트에서 발견 된 바로 그 픽스입니다. 아직도 내 대답에 만족하지 않습니다.

제 질문을 읽으면 CA가 리눅스 컴퓨터에서 만들어졌으며 클라이언트와 서버의 인증서가 해당 CA에 의해 서명되었음을 알 수 있습니다. 해당 호스트는 다른 VMWare VM이며 "VM3"이라고합니다. 클라이언트 및 서버의 "VM3"에서 "CA123"을 사용하여 생성 한 인증서는 클라이언트 VM ("VM1") 및 서버 VM ("VM2")에서 작동하지 않습니다. 호기심에서 VM2에 CA를 설치하고 클라이언트 및 서버 인증서에 서명을 시도하고 클라이언트 인증서를 클라이언트 VM에 복사하려고했습니다. 놀랍게도, 그것은 효과가 있지만, 나는 왜 그런지 모른다. VM3에서 어떤 종류의 의존성을 만들었는지 대답 할 수 없습니다.

보다 정확하고 완전한 대답을 자유롭게 게시하십시오.

+0

마침내 알아 냈습니까?아마도 CA와 인증서를 생성하는 커맨드 라인이 중요한 것 같아요. 게시 해주세요. – tedyyu