Сообщение CLIENT - HELLO
char MSG-CLIENT-HELLO
char CLIENT-VERSION-MSB
char
CLIENT-VERSION-LSB
char CIPHER-SPECS-LENGTH-MSB
char
CIPHER-SPECS-LENGTH-LSB
char SESSION-ID-LENGTH-MSB
char
SESSION-ID-LENGTH-LSB
char CHALLENGE-LENGTH-MSB
char
CHALLENGE-LENGTH-LSB
char CIPHER-SPECS-DATA[(MSB<<8)|LSB]
char
SESSION-ID-DATA[(MSB<<8)|LSB]
char
CHALLENGE-DATA[(MSB<<8)|LSB]
Когда клиент впервые подключается к серверу, он должен послать сообщение CLIENT-HELLO. Сервер ожидает это сообщение от клиента первым. Любое другое сообщение от клиента в данных обстоятельствах рассматривается как ошибка.
Клиент посылает серверу свою версию SSL, спецификацию шифров, некоторые данные вызова (challenge data), и данные идентификатора сессии. Данные идентификатора сессии посылаются клиентом только в том случае, когда в его кэше имеется идентификатор сессии, а значение SESSION-ID-LENGTH не равно нулю. Когда идентификатора сессии нет, то значение SESSION-ID-LENGTH должно быть равно нулю. Данные вызова используются для аутентификации сервера. После того как клиент и сервер согласовали пару ключей сессии, сервер присылает сообщение SERVER-VERIFY с зашифрованной формой CHALLENGE-DATA.
Заметим также, что сервер не пошлет сообщения SERVER-HELLO пока не получит сообщения CLIENT-HELLO. Это делается так, чтобы сервер мог в первом сообщении клиенту определить состояние идентификатора сессии клиента (т.e. улучшить эффективность протокола и уменьшить объем обменов).
Сервер рассматривает сообщение CLIENT-HELLO и проверяет, поддерживает ли он версию программы клиента и хотя бы одну позицию в спецификации шифров клиента. Сервер может опционно отредактировать спецификацию шифров, удалив записи, которые он решил не поддерживать. Отредактированная версия будет прислана в сообщении SERVER-HELLO, если идентификатор сессии не находится в кэше сервера.
Значение CIPHER-SPECS-LENGTH должно быть больше нуля и кратно 3. Код SESSION-ID-LENGTH должен быть равен нулю или 16. Значение CHALLENGE-LENGTH должно быть больше чем ³ 16 и £ 32.
Это сообщение должно быть первым, посланным клиентом серверу. После его посылки клиент ждет сообщения SERVER-HELLO. Любое другое сообщение, присланное сервером (кроме ERROR) не допустимо.
Сообщение CLIENT - MASTER - KEY
char MSG-CLIENT-MASTER-KEY
char CIPHER-KIND[3]
char
CLEAR-KEY-LENGTH-MSB
char CLEAR-KEY-LENGTH-LSB
char
ENCRYPTED-KEY-LENGTH-MSB
char ENCRYPTED-KEY-LENGTH-LSB
char
KEY-ARG-LENGTH-MSB
char KEY-ARG-LENGTH-LSB
char
CLEAR-KEY-DATA[MSB<<8|LSB]
char
ENCRYPTED-KEY-DATA[MSB<<8|LSB]
char
KEY-ARG-DATA[MSB<<8|LSB]
Клиент посылает это сообщение, когда он определил мастерный ключ для работы с сервером. Заметим, что когда идентификатор сессии согласован, это сообщение не посылается.
Поле CIPHER-KIND указывает, какой шифр выбран из спецификации CIPHER-SPECS сервера.
Данные CLEAR-KEY-DATA содержат открытую часть MASTER-KEY. CLEAR-KEY-DATA комбинируются с SECRET-KEY-DATA, чтобы образовать MASTER-KEY, при этом SECRET-KEY-DATA составляет младшие байты MASTER-KEY. ENCRYPTED-KEY-DATA содержит секретные части MASTER-KEY, зашифрованные с использованием общедоступного ключа сервера. Шифруемые блоки формируются с использованием блоков типа 2 PKCS#1. Информационная часть блока имеет следующий формат:
char SECRET-KEY-DATA[SECRET-LENGTH]
SECRET-LENGTH равно числу байт каждого из ключей сессии. SECRET-LENGTH плюс CLEAR-KEY-LENGTH равно числу байт в ключе шифра (как это определено CIPHER-KIND). Если после дешифрования SECRET-LENGTH окажется неравным ожидаемому значению, регистрируется ошибка. Ошибкой считается и ситуация, когда CLEAR-KEY-LENGTH не равно нулю и CIPHER-KIND является не экспортным шифром.
Если алгоритм ключа требует аргумента (например, вектора инициализации DES-CBC), тогда поле KEY-ARG-LENGTH будет ненулевым и KEY-ARG-DATA будет содержать соответствующую информацию. Для алгоритмов SSL_CK_RC2_128_CBC_WITH_MD5, SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5, SSL_CK_IDEA_128_CBC_WITH_MD5, SSL_CK_DES_64_CBC_WITH_MD5 и SSL_CK_DES_192_EDE3_CBC_WITH_MD5 должны присутствовать данные KEY-ARG с длиной 8 байт.
Вычисление ключей сессии клиента и сервера является функцией CIPHER-CHOICE:
SSL_CK_RC4_128_WITH_MD5
SSL_CK_RC4_128_EXPORT40_WITH_MD5
SSL_CK_RC2_128_CBC_WITH_MD5
SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5
SSL_CK_IDEA_128_CBC_WITH_MD5
KEY-MATERIAL-0
= MD5[ MASTER-KEY, "0", CHALLENGE, CONNECTION-ID ]
KEY-MATERIAL-1 =
MD5[ MASTER-KEY, "1", CHALLENGE, CONNECTION-ID ]
CLIENT-READ-KEY =
KEY-MATERIAL-0[0-15]
CLIENT-WRITE-KEY = KEY-MATERIAL-1[0-15]
Где KEY-MATERIAL-0[0-15] означает первые 16 байт данных KEY-MATERIAL-0, с KEY-MATERIAL-0[0], образующим старший байт CLIENT-READ-KEY.
Данные передаются хэш-функции MD5, начиная с MASTER-KEY, далее следует "0" или "1", затем вызов (CHALLENGE) и, наконец, CONNECTION-ID.
Заметим, что "0" означает ASCII символ нуль (0x30), а не значение нуль. "1" означает ASCII символ 1 (0x31). MD5 выдает 128 бит выходных данных, которые используются в качестве ключа алгоритма шифрования (старший байт хэша MD5 становится старшим байтом ключевого материала).
SSL_CK_DES_64_CBC_WITH_MD5
KEY-MATERIAL-0 = MD5[
MASTER-KEY, CHALLENGE, CONNECTION-ID ]
CLIENT-READ-KEY =
KEY-MATERIAL-0[0-7]
CLIENT-WRITE-KEY = KEY-MATERIAL-0[8-15]
Для DES-CBC, 16-байтовый ключевой материал формируется с помощью MD5. Первые 8 байт дайджеста MD5 используются в качестве CLIENT-READ-KEY, в то время как оставшиеся 8 байт используются в качестве CLIENT-WRITE-KEY. Вектор инициализации берется из KEY-ARG-DATA.
SSL_CK_DES_192_EDE3_CBC_WITH_MD5
KEY-MATERIAL-0 = MD5[ MASTER-KEY, "0", CHALLENGE,
CONNECTION-ID ]
KEY-MATERIAL-1 = MD5[ MASTER-KEY, "1", CHALLENGE,
CONNECTION-ID ]
KEY-MATERIAL-2 = MD5[ MASTER-KEY, "2", CHALLENGE,
CONNECTION-ID ]
CLIENT-READ-KEY-0 =
KEY-MATERIAL-0[0-7]
CLIENT-READ-KEY-1 =
KEY-MATERIAL-0[8-15]
CLIENT-READ-KEY-2 =
KEY-MATERIAL-1[0-7]
CLIENT-WRITE-KEY-0 = KEY-MATERIAL-1[8-15]
CLIENT-WRITE-KEY-1 = KEY-MATERIAL-2[0-7]
CLIENT-WRITE-KEY-2 =
KEY-MATERIAL-2[8-15]
Данные передаются хэш-функции MD5 в указанном порядке, слева направо: первым поступает MASTER-KEY, затем "0", "1" или "2", далее CHALLENGE и, наконец, CONNECTION-ID (идентификатор сессии).
Заметим, что "0" означает ascii символ нуль (0x30), а не код нуль. "1" означает ascii символ 1 (0x31). "2" означает ascii символ 2 (0x32).
Всего генерируется 6 ключей, 3 ключа читающей стороны для шифра DES-EDE3 и 3 - для пишущей стороны для функции DES-EDE3. Вектор инициализации формируется в KEY-ARG-DATA.
Вспомним, что MASTER-KEY передан серверу в сообщении CLIENT-MASTER-KEY. CHALLENGE выдается серверу клиентом в сообщении CLIENT-HELLO. CONNECTION-ID передается клиенту от сервера в сообщении SERVER-HELLO. Это делает получаемые в результате ключи, зависящими от исходной и текущей сессии. Заметим, что мастерный ключ никогда не используется для шифрования данных, и следовательно не может быть легко раскрыт.
Сообщение CLIENT-MASTER-KEY должно быть послано после сообщения CLIENT-HELLO и до сообщения CLIENT-FINISHED. Сообщение CLIENT-MASTER-KEY должно быть послано, если сообщение SERVER-HELLO содержит значение SESSION-ID-HIT равное 0.
Сообщение CLIENT - CERTIFICATE
char MSG-CLIENT-CERTIFICATE
char
CERTIFICATE-TYPE
char CERTIFICATE-LENGTH-MSB
char
CERTIFICATE-LENGTH-LSB
char RESPONSE-LENGTH-MSB
char
RESPONSE-LENGTH-LSB
char CERTIFICATE-DATA[MSB<<8|LSB]
char
RESPONSE-DATA[MSB<<8|LSB]
Это сообщение посылается клиентом SSL в ответ на сообщение сервера REQUEST-CERTIFICATE. CERTIFICATE-DATA содержит данные, определенные значением CERTIFICATE-TYPE. Сообщение об ошибке ERROR посылается с кодом NO-CERTIFICATE-ERROR, если данный запрос не может быть обработан корректно (например, получатель сообщения не имеет зарегистрированного сертификата). CERTIFICATE-TYPE является одним из:
SSL_X509_CERTIFICATE
CERTIFICATE-DATA содержит
подписанный сертификат X.509 (1988).
RESPONSE-DATA несет в себе аутентификационные данные отклика. Эти данные зависят от значения AUTHENTICATION-TYPE, посланного сервером.
Когда код AUTHENTICATION-TYPE равен SSL_AT_MD5_WITH_RSA_ENCRYPTION, тогда RESPONSE-DATA содержит цифровую подпись следующих компонентов (в указанном порядке):
Цифровая подпись формируется с привлечением MD5, полученный хэш шифруется с использованием общедоступного ключа клиента, формат подписи согласуется со стандартом PKCS#1. Сервер аутентифицирует клиента путем верификации его цифровой подписи. Допускается добавление нового типа AUTHENTICATION-TYPE или идентификатора алгоритма цифровой подписи.
Это сообщение должно быть послано клиентом только в ответ на сообщение REQUEST-CERTIFICATE сервера.
Сообщение CLIENT - FINISHED
char MSG-CLIENT-FINISHED
char CONNECTION-ID[N-1]
Клиент посылает это сообщение, после успешной обработки соответствующего сообщения сервера. Заметим, что клиент должен быть готов к приему сообщений от сервера, пока не получит сообщение SERVER-FINISHED. Данные CONNECTION-ID представляют собой исходный идентификатор соединения сервера, посланный в его сообщении SERVER-HELLO и зашифрованный посредством согласованного ключа сессии.
"N" равно числу байт в посланном сообщении, таким образом "N-1" равно числу байт в сообщении за вычетом одного байта заголовка.
Для версии протокола 2, клиент должен посылать это сообщение после получения сообщения SERVER-HELLO. Если в сообщении SERVER-HELLO флаг SESSION-ID-HIT не равен нулю, тогда сообщение CLIENT-FINISHED посылается немедленно, в противном случае сообщение CLIENT-FINISHED посылается после сообщения CLIENT-MASTER-KEY.