2015-02-07 2 views
0

후 ssl (openssl) 소켓에 쓸 수 없습니다. 안녕하세요, 저는 C++로 SMTP 클라이언트를 작성하려고합니다. SSL_write 전) STARTTLS

32096:error:140790E5:SSL routines:SSL23_write::ssl handshake failure 

내가 (SSL_do_handshake을 시도하고 작동하십시오 "EHLO ..."하고 STARTTLS 명령 후 는 연결이 내가() SSL_write을하려고 할 때이 오류가 괜찮을 것 같다.

다음은 SSL 부분에 대한 코드입니다.

typedef struct { 
    int socket; 
    SSL *sslHandle; 
    SSL_CTX *sslContext; 
} SSLConnection; 

SSLConnection* wrapSslSocket(SOCKET hSocket) 
{ 
    SSLConnection *c; 
    c = (SSLConnection *)malloc (sizeof (SSLConnection)); 
    c->sslHandle = NULL; 
    c->sslContext = NULL; 
    c->socket = hSocket; 
    if (c->socket) 
    { 
     // Register the error strings for libcrypto & libssl 
     SSL_load_error_strings(); 
     // Register the available ciphers and digests 
     SSL_library_init(); 

     c->sslContext = SSL_CTX_new (SSLv23_client_method()); //I tried SSLv23, SSLv3, SSLv2, TLSv1.2 TLSv1.1, TLSv1.0 
     if (c->sslContext == NULL) 
      ERR_print_errors_fp (stderr); 

     // Create an SSL struct for the connection 
     c->sslHandle = SSL_new (c->sslContext); 
     if (c->sslHandle == NULL) 
      ERR_print_errors_fp (stderr); 

     // Connect the SSL struct to our connection 
     if (!SSL_set_fd (c->sslHandle, c->socket)) 
      ERR_print_errors_fp (stderr); 

     if (!SSL_set_mode(c->sslHandle, SSL_MODE_AUTO_RETRY)) 
      ERR_print_errors_fp (stderr); 

     // Initiate SSL handshake 
     if (SSL_connect (c->sslHandle) != 1) 
      ERR_print_errors_fp (stderr); 
    } 
    return c; 
} 



// Read all available text from the connection 
int sslRead (SSLConnection *c) 
{ 
    const int readSize = 1024; 
    char buffer[1024]; 
    int cb; 
    int cbBuffer = 0; 

if (c) 
{ 
    while (1) 
    {  
     cb = SSL_read(c->sslHandle, buffer + cbBuffer, sizeof(buffer) - 1 - cbBuffer); 
     if(cb <= 0) 
     { 
      ERR_print_errors_fp (stderr); 
      return -1; 
     } 
     cbBuffer += cb; 
     if(memcmp(buffer + cbBuffer - 2, "\r\n", 2) == 0) 
     { 
      buffer[cbBuffer] = '\0'; 
      break; 
     } 
    } 
} 
    printf("ssl send : %s \n",buffer); 
    char status[3]; 
    memcpy(status,buffer, 3*sizeof(char)); 
    status[3] = '\0'; 
    return atoi(status); 
} 

// Write text to the connection 
int sslWrite (SSLConnection *c, char *text) 
{ 
    if (c) 
    { 
     int v = SSL_do_handshake(c->sslHandle); 
     ERR_print_errors_fp (stderr); 
     return SSL_write (c->sslHandle, text, strlen (text)); 
    } 
} 

I 포트 smtp.gmail.com 587 개

감사

답변

0

을에 테스트하고있어 당신은 스콧 포드의 sslclient을 (http://www.superscript.com/ucspi-ssl/sslclient.html 참조)을 사용하는 것이 좋습니다. sslclient는 프로그램을 생성하고 서버에 대한 TCP 연결을 열고 프로그램의 stdout을 서버에 파이프하고 서버의 출력을 프로그램의 표준 입력으로 파이프합니다. 그는 일반 텍스트로 연결을 시작하는 TLS 용 포크 버전을 가지고 있습니다. 그런 다음 양측이 STARTTLS에 동의하면 프로그램이 sslcient에이를 알리고이 연결에 대한 파일 디스크립터에 명령을 작성하여 SSL 암호화를 활성화 할 수 있습니다 목적 (https://github.com/SuperScript/ucspi-ssl/pull/1 참조). 이런 식으로하면 sslclient를 사용하여 소켓 및 SSL 등을 설정할 때까지 모든 무거운 작업을 수행 할 수 있으며 프로그램의 핵심 기능에 집중할 수 있습니다.

관련 문제