невозможно записать в сокет ssl (openssl) после STARTTLS

Привет, я пытаюсь написать SMTP-клиент на C ++.
После команды «ehlo …» и команды STARTTLS соединение кажется нормальным. Я получаю эту ошибку при попытке SSL_write ():

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

Я пытался SSL_do_handshake () до 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));
}
}

Я тестирую на smtp.gmail.com порт 587

Спасибо

0

Решение

Вы можете рассмотреть возможность использования Скотта Гиффорда sslclient (увидеть http://www.superscript.com/ucspi-ssl/sslclient.html). sslclient порождает вашу программу и открывает tcp-соединение с сервером, направляет стандартный вывод вашей программы на сервер и направляет вывод с сервера на стандартный вывод вашей программы. У него есть раздвоенная версия для TLS, которая запускает соединение в виде обычного текста, а затем, как только обе стороны договорились о STARTTLS, ваша программа может дать команду sslcient разрешить шифрование SSL для соединения, записав команду для дескриптора файла для этого. цель (см. https://github.com/SuperScript/ucspi-ssl/pull/1). Делая это таким образом, вы можете использовать sslclient, чтобы выполнить всю тяжелую работу, вплоть до настройки сокетов, ssl и т. Д., И вы можете сосредоточиться на основной функции вашей программы.

0

Другие решения


По вопросам рекламы [email protected]