Подготовка защищенного сокет-соединения

Для перевода сокет-соединения в защищенное состояние и его проверки в MQL5 существует пара функций: SocketTlsHandshake и SocketTlsCertificate, соответственно. Как правило, нам не требуется "вручную" включать защиту вызовом SocketTlsHandshake, если соединение устанавливается на порту 443. Дело в том, что он является стандартным для HTTPS (TLS).

Принцип работы защиты основан на шифровании потока данных между клиентом и сервером, для чего изначально используется пара асимметричных ключей: открытого и закрытого. Мы уже касались этой темы в разделе Обзор доступных методов преобразования информации. Каждый уважающий себя сайт приобретает цифровой сертификат у одного из удостоверяющих центров, которым доверяет сетевое сообщество. Сертификат содержит публичный ключ сайта и подписан цифровой подписью центра. Браузеры и прочие клиентские приложения хранят (или могут импортировать) публичные ключи удостоверяющих центров и потому могут убедиться в качестве конкретного сертификата.

Установление защищенного TLS-соединения

Установление защищенного TLS-соединения
(рисунок из инета)

Далее при подготовке защищенного соединения браузер или приложение генерирует некий "секрет", шифрует его открытым ключом сайта и отправляет ему, а сайт расшифровывает известным только ему закрытым ключом. Данный этап на практике выглядит более сложно, но в результате и клиент, и сервер обладают ключом шифрования для текущей сессии (соединения). Этот ключ используется обоими участниками коммуникации для шифрования последующих запросов и ответов на одном конце и расшифровки на другом.

Функция SocketTlsHandshake инициирует защищенное TLS-соединение с указанным хостом по протоколу TLS Handshake. При этом клиент и сервер согласовывают параметры соединения: версию используемого протокола и способ шифрования данных.

bool SocketTlsHandshake(int socket, const string host)

В параметрах функции передается дескриптор сокета и адрес сервера, с которым установлено соединение (по сути, это — то же имя, которое указывалось в SocketConnect).

До защищенного соединения программа должна предварительно установить обычное TCP-соединение с хостом при помощи SocketConnect.

Функция возвращает true в случае успеха, а иначе — false. При ошибке в _LastError записывается код 5274 (ERR_NETSOCKET_HANDSHAKE_FAILED).

Функция SocketTlsCertificate получает данные о сертификате, используемом для защиты сетевого соединения.

int SocketTlsCertificate(int socket, string &subject, string &issuer, string &serial, string &thumbprint, datetime &expiration)

Если для сокета установлено защищенное соединение (либо после явного и успешного вызова SocketTlsHandshake, либо после подключения по порту 443), то данная функция по дескриптору сокета заполняет все остальные ссылочные переменные соответствующей информацией: именем владельца сертификата (subject), именем издателя сертификата (issuer), серийным номером (serial), цифровым отпечатком (thumbprint) и сроком действия (expiration) сертификата.

Функция возвращает true в случае успешного получения сведений о сертификате или false в результате ошибки. Код ошибки при этом — 5275 (ERR_NETSOCKET_NO_CERTIFICATE). Это можно использовать для определения того факта, установилось ли соединение, открытое функцией SocketConnect, сразу в защищенном режиме. Мы воспользуемся этим в примере, в следующем разделе.