Первоначальной целью протокола TLS (Transport Layer Security, RFC-2246) является обеспечение конфиденциальности и целостности данных при коммуникации двух приложений. Протокол имеет два уровня: протокол записей TLS и протокол диалога TLS. На нижнем уровне, работающем поверх надежного транспортного протокола (напр., TCP [TCP]), размещается протокол записей TLS. Этот протокол обеспечивает безопасность соединений, которые имеют два основных свойства.
Протокол записей TLS используется для инкапсуляции различных протоколов высокого уровня. Один из таких инкапсулируемых объектов, протокол диалога TLS, позволяет серверу и клиенту аутентифицировать друг друга и согласовать алгоритм шифрования и крипто-ключи, до того как приложение передаст или примет первый байт информации. Протокол диалога TLS обеспечивает безопасное соединение, которое имеет три базовых свойства.
Одним из преимуществ TLS является то, что он не зависит от протокола приложения. Протоколы верхнего уровня могут размещаться поверх протокола TLS прозрачным образом. Стандарт TLS, однако, не специфицирует то, как протоколы увеличивают безопасность с помощью TLS ; решение о том, как инициализировать TLS -диалог и как интерпретировать сертификаты аутентификации, оставляется на усмотрение разработчиков протоколов и программ, которые работают поверх TLS.
Целями протокола TLS в порядке приоритетности являются:
Представление данных в этом документе напоминает синтаксис языка Си и XDR [XDR], но эти параллели достаточно приблизительны и не имеют никакого отношения к самому протоколу TLS. Эти представления применены лишь для целей упрощения восприятия материала.
Базовым блоком данных считается один байт (т.e. 8 бит). Многобайтовые информационные элементы представляют собой объединение последовательности байтов слева направо и сверху вниз. Многобайтовые элементы извлекаются из байтового потока (используя нотацию Си) следующим образом:
value = (байт[0] << 8*(n-1)) | (байт[1] << 8*(n-2)) | ... | байт[n-1];
Этот порядок байтов для многобайтовых последовательностей является стандартным для сетей (big endian).
Комментарии начинаются с "/*" и завершаются "*/". Опционные компоненты выделяются с помощью помещения их в двойные квадратные скобки "[[ ]]". Однобайтовые объекты, содержащие не интерпретируемые данные, имеют непрозрачный тип (opaque).
Вектор (одномерный массив) является потоком однородных информационных элементов. Размер вектора может быть специфицирован во время документирования или оставаться не специфицированным вплоть до начала работы. В любом случае длина определяет число байтов, а не число элементов в векторе. Синтаксис спецификации нового типа T', который является вектором фиксированной длины типа T, имеет вид TT'[n] ;
Здесь T' занимает в информационном потоке n байт, где n кратно размеру T. Длина вектора не включается в кодированный поток.
В следующем примере Datum определен как три последовательные байта, которые не интерпретируются протоколом, в то время как Data представляет собой три вектора Datum, состоящие из девяти байт.
opaque Datum[3]; /* три не интерпретируемые байта */ Datum Data[9]; /* 3 последовательных 3-байтовых вектора */
Векторы переменной длины определяются путем спецификации субдиапазона легальных длин, используя нотацию <floor..ceiling>. При кодировании реальная длина предшествует потоку байтов, образующих вектор. Длина имеет форму числа, занимающего столько байт, сколько нужно, чтобы специфицировать максимально возможную длину вектора ( ceiling ). Вектор переменной длины с действительным полем длины равным нулю является пустым вектором.
T T' <floor..ceiling>;
В следующем примере, обязательным является вектор, который должен содержать от 300 до 400 байт непрозрачного типа. Он не должен быть пустым. Поле действительной длины занимает два байта, uint16, достаточных, чтобы представить значение 400. С другой стороны, longer может представить до 800 байт данных, или 400 uint16 элементов, и может быть пустым. Его кодовое представление будет включать два байта поля реальной длины, за которым будет следовать вектор. Длина закодированного вектора должна быть четной, кратной длине одиночного элемента (например: 17-байтовый вектор uint16 будет нелегальным ).
opaque mandatory<300..400>; /* поле длины имеет 2 байта, не может быть пустым */ uint16 longer<0..800>; /* 0 - 400 16-битовое целое число без знака */
Базовый числовой тип данных представляет собой байт без знака ( uint8 ). Все более длинные типы цифровых данных образуются из фиксированной последовательности байт без знака, объединенных вместе. Следующие числовые типы являются предопределенными.
uint8 uint16[2]; uint8 uint24[3]; uint8 uint32[4]; uint8 uint64[8];
Все значения здесь и в дальнейшем записываются в сетевом порядке (big-endian); uint32 представленное шестнадцатеричными байтами 01 02 03 04 эквивалентно десятичному значению 16909060.
Еще одним типом данных является enum ( enumerated ). Поле типа enum предполагает, что величина декларирована при определении. Каждое определение дает новый тип. Только нумерованные элементы того же типа могут присваиваться и сравниваться. Каждому нумерованному элементу должно быть присвоено значение, как это показано в следующем примере. Так как нумерованные элементы неупорядочены, им может быть присвоено любое уникальное значение в любом порядке.
enum { e1(v1), e2(v2), ... , en(vn) [[, (n)]] } Te;
Нумерованные элементы занимают в байтовом потоке столько места, сколько требует максимальное определенное порядковое значение. Следующее определение требует использования одного байта для поля типа Color (цвет).
enum { red(3), blue(5), white(7) } Color;
Можно опционно специфицировать значение без ассоциированной с ним метки, чтобы задать ширину без определения избыточного элемента. В следующем примере Taste в потоке данных занимает два байта, но может предполагать значения 1, 2 или 4.
enum { sweet(1), sour(2), bitter(4), (32000) } Taste;
Имена элементов нумерации собраны в пределах определенного типа. В первом примере полная ссылка на второй элемент будет выглядеть как Color.blue. Такое описание не требуется, если объект присвоения ( target ) хорошо специфицирован.
Color color = Color.blue; /* чрезмерная спецификация, допустимо */ Color color = blue; /* правильно, тип задан неявно */
Для нумерованных элементов, которые не преобразуются во внешнее представление, цифровая информация может быть опущена.
enum { low, medium, high } Amount;