Недавно, 4 сентября, я начал разработку библиотеки TLS. Первую неделю я читал документацию и прикидывал, насколько реально это сделать. Затем начал кодировать. За основу я взял старую версию TLS (1.0), потом можно будет модернизировать до 1.2. До завершения еще далеко, но кое-что уже есть. Программа может подключиться к https-серверу, обменяться ключами, отправить прикладной запрос и прочитать ответ. Парсер сертификатов я пока не сделал, а просто захардкодил открытый ключ Википедии.
Надо запустить программу и ввести в консоли "en.wikipedia.org/wiki/Main_Page" или "en.wikipedia.org/wiki/KolibriOS" (регистр имеет значение). Программа обменяется ключами и отправит запрос
GET /wiki/??? HTTP/1.1
Host: en.wikipedia.org
Полученный ответ будет показан в консоли и сохранен в файле /tmp0/1/1.txt.
Пока программа работает довольно медленно: криптографические алгоритмы очень тяжелые, O7/11 тут не справляется. Вроде бы, где-то здесь были готовые алгоритмы на асме, я пока их не рассматривал, но в будущем, конечно, надо применить ассемблерные решения. Даже на Core i7 требуется ~3 сек для вычисления RSA. 3DES работает со скоростью 60-70 кбайт/c. Небыстро...
Кстати, сервер Википедии иногда, вместо нормального ответа возвращает предупреждение, что, дескать, ваш "браузер" (IE 8.0, Windows XP) устарел и поддержка 3DES прекращается. Я знал, что 3DES устарел, но думал, что он еще вполне поддерживается. Просто мне показалось, что 3DES проще сделать, чем AES. Но всё равно надо перейти на AES.
При первом запуске программы, соединение с сервером устанавливается не сразу, а примерно через минуту. Программа пишет "connecting..." а дальше надо ждать. Есть какая-то проблема с сокетами. При последующих запусках, когда сокеты "прогрелись", соединение устанавливается незамедлительно.
Максимальный размер ответа ограничен 4 Мб -- если больше, будет аварийная ситуация. Оперативной памяти программа тратит тоже немало (40-50 Мб), но это вроде несложно уменьшить.
Пока всё очень ненадежно и медленно. Но начало положено...
Так выглядит в NetSurf главная страница Википедии, которая была загружена этой программой.
----
05-oct-2017
Увеличена скорость получения данных из сети.
Добавлены функции AES и SHA256.
список поддерживаемых шифронаборов:
TLS_RSA_WITH_3DES_EDE_CBC_SHA (устарел)
TLS_RSA_WITH_AES_128_CBC_SHA
TLS_RSA_WITH_AES_256_CBC_SHA
TLS_RSA_WITH_AES_128_CBC_SHA256 (TLS 1.2)
TLS_RSA_WITH_AES_256_CBC_SHA256 (TLS 1.2)
последние два используются только с TLS 1.2, пока не нужно, но потом пригодятся.
Сервер перестал присылать сообщения об устаревшем 3DES. К тому же, AES работает намного быстрее.
----
15-oct-2017
Сделана обработка ошибок, оптимизация по памяти, улучшена внутренняя структура, готовится преобразование программы в библиотеку: убраны почти все глобальные переменные, сформирован интерфейс будущей библиотеки. Остается еще много мелких недоработок + парсер сертификатов.
----
22-oct-2017
Большой прогресс. Сделан простой парсер сертификатов (программа подключается только к Wikipedia, но теперь открытый ключ не встроен в программу, а извлекается из сертификата сервера). Предусмотрена возможность возобновления сессии. Сделана обработка сетевых событий. Снято ограничение на размер ответа. Повышена надежность работы программы. Оптимизирован алгоритм AES -- теперь на мощных машинах он работает в несколько раз быстрее, чем сетевая подсистема в KolibriOS.
Остается сделать кое-какую мелочь, преобразовать программу в библиотеку, написать примеры использования и описание функций.
TLS (клиент)
-
Last edited by akron1 on Sat Oct 28, 2017 3:10 pm, edited 5 times in total.
Очень полезное и серьезное начинание.
Из хаоса в космос
Good work! Glad to see that someone tackles it!
Когда-то я делал алгоритм шифрования des посмотреть можно здесь:
http://websvn.kolibrios.org/listing.php ... 162e2aad94
А алгоритм aes делал diamond для программы kfar:
http://websvn.kolibrios.org/filedetails ... %2Faes.inc
http://websvn.kolibrios.org/listing.php ... 162e2aad94
А алгоритм aes делал diamond для программы kfar:
http://websvn.kolibrios.org/filedetails ... %2Faes.inc
Nice work akron1, have you seen http://board.kolibrios.org/viewtopic.php?f=24&t=3290 ?
"Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius -- and a lot of courage -- to move in the opposite direction." Albert Einstein
hidnplayr,
Yes, I know about that work, but I don't code in asm.
Yes, I know about that work, but I don't code in asm.
What language did you write this in?
Do you care to share the source code? Maybe it can be used to improve ASM version
Do you care to share the source code? Maybe it can be used to improve ASM version
"Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius -- and a lot of courage -- to move in the opposite direction." Albert Einstein
Oberon-07/11. This compiler is another my work. Later the cryptographic algorithms will be replaced by those written in C (or asm). But it's not yet soon.
Yes, I'll share the source code. But it's still early.
Yes, I'll share the source code. But it's still early.
Cool, keep up the good work!
"Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius -- and a lot of courage -- to move in the opposite direction." Albert Einstein
Hello akron1
This looks pretty useful for Netsurf as well to support HTTPS.
Maybe I'll be able to incorporate it into Netsurf once this is matured enough.
This looks pretty useful for Netsurf as well to support HTTPS.
Maybe I'll be able to incorporate it into Netsurf once this is matured enough.
---
Check out the Netsurf Web Browser for KolibriOS.
Read the wiki and happy hacking with KolibriOS!
Check out the Netsurf Web Browser for KolibriOS.
Read the wiki and happy hacking with KolibriOS!
ashmew2
I hope it will be possible. I continue to develop...
I hope it will be possible. I continue to develop...
Программа преобразована в библиотеку. Пока еще есть недоработки, но уже можно пробовать ее использовать.
Вероятно, есть проблемы с сетевой подсистемой KolibriOS: иногда библиотека не может открыть сокет и возвращает код ошибки -23. Библиотека сделана с возможностью компиляции как для KolibriOS, так и для Windows (я вынес все системные зависимости в один модуль). Компиляция для Windows мне нужна для упрощения разработки и тестирования. Поэтому библиотека содержит небольшую избыточность. В Windows всё работает безотказно. В KolibriOS -- то не открывается сокет, то теряется соединение.
Пока я возьму паузу и продолжу после нового года. Планирую сделать:
- поддержку TLS 1.1 и 1.2
- заменить криптоалгоритмы на высокоэффективные, написанные на асме или C (прежде всего RSA)
- улучшить надежность работы
- возможно переписать отдельные части или даже всё. Я впервые писал сетевое приложение и многие особенности работы с сетью мне были неизвестны. И поэтому, то, что я написал мне не нравится. Теперь, когда есть работающая реализация и получен опыт, написать новую будет несложно.
Описание функций
инициализировать библиотеку.
Приложение обязательно должно вызвать эту функцию после загрузки библиотеки.
______________
void *open (void *session, int b1, int b2, int b3, int b4, int port, int buf_size, int &error)
открыть сессию
- session -- указатель на session_id и master_secret ранее открытой сессии или 0, если эта сессия первая
- b1, b2, b3, b4 -- IP сервера
- port -- порт (для https port = 443)
- buf_size -- размер буфера для временного хранения данных до передачи в приложение. Приложение должно
читать данные как можно быстрее, иначе буфер будет заполнен, приём данных от сервера остановится и
соединение может быть потеряно. Это не проблема библиотеки -- при работе под Windows, даже если приложение
читает данные медленно, соединение не теряется. В настоящее время, допустимый размер буфера 256 Кб - 256 Мб.
На самом деле, библиотека создает два буфера заданного размера. Буферы кольцевые: если достигнут конец
буфера, то данные будут записаны в начало, если начало уже прочитано приложением. При быстрой работе
приложения и медленной работе сети, переполнение буферов не происходит.
- error -- возвращаемый код ошибки (отрицательное число), 0 -- успех.
результат: указатель на параметры соединения, 0 -- ошибка
______________
void session (void *params, void *buffer)
получить session_id и master_secret ранее открытой (и еще не закрытой!) сессии
- params -- указатель на параметры соединения ранее открытой сессии
- buffer -- адрес памяти, куда будет записан результат (81 байт минимум). Это можно использовать для открытия
следующей сессии с тем же сервером (функция open, параметр session), чтобы повторно не вычислять RSA
(алгоритм RSA работает медленно).
______________
void close (void **params)
закрыть сессию, освободить память
- params -- указатель на параметры соединения. Будет присвоено значение 0.
______________
int send (void *params, void *buffer, int size)
отправить данные
- params -- указатель на параметры соединения
- buffer -- указатель на данные
- size -- размер данных
результат: 0 -- успех, иначе код ошибки
______________
int recv (void *params, void *buffer, int size)
получить данные
- params -- указатель на параметры соединения
- buffer -- указатель на буфер для данных
- size -- размер буфера
результат:
>= 0 -- количество записанных в буфер байтов.
-17 -- сервер завершил передачу данных и закрыл сессию. После этого необходимо вызвать close,
чтобы освободить память.
< 0 (!= -17) -- код ошибки.
______________
Общий порядок вызовов:
open
session (необязательно)
send
recv
close
Cоглашение вызовов stdcall.
Рекомендуемый минимальный размер стэка приложения 256 Кб.
----
03-nov-2017
До перерыва, я всё же сделал одно небольшое, но важное улучшение. Я переделал алгоритм RSA (изменил форму представления длинных чисел и сделал предварительные вычисления). Теперь RSA работает в 7 раз быстрее. На Core i7 время работы алгоритма сократилось с 2250 мс до 320 мс. Приложению требуется дополнительно 64 Кб стэка для хранения результатов предварительных вычислений.
Вероятно, есть проблемы с сетевой подсистемой KolibriOS: иногда библиотека не может открыть сокет и возвращает код ошибки -23. Библиотека сделана с возможностью компиляции как для KolibriOS, так и для Windows (я вынес все системные зависимости в один модуль). Компиляция для Windows мне нужна для упрощения разработки и тестирования. Поэтому библиотека содержит небольшую избыточность. В Windows всё работает безотказно. В KolibriOS -- то не открывается сокет, то теряется соединение.
Пока я возьму паузу и продолжу после нового года. Планирую сделать:
- поддержку TLS 1.1 и 1.2
- заменить криптоалгоритмы на высокоэффективные, написанные на асме или C (прежде всего RSA)
- улучшить надежность работы
- возможно переписать отдельные части или даже всё. Я впервые писал сетевое приложение и многие особенности работы с сетью мне были неизвестны. И поэтому, то, что я написал мне не нравится. Теперь, когда есть работающая реализация и получен опыт, написать новую будет несложно.
Описание функций
Spoiler:
void lib_init (void)инициализировать библиотеку.
Приложение обязательно должно вызвать эту функцию после загрузки библиотеки.
______________
void *open (void *session, int b1, int b2, int b3, int b4, int port, int buf_size, int &error)
открыть сессию
- session -- указатель на session_id и master_secret ранее открытой сессии или 0, если эта сессия первая
- b1, b2, b3, b4 -- IP сервера
- port -- порт (для https port = 443)
- buf_size -- размер буфера для временного хранения данных до передачи в приложение. Приложение должно
читать данные как можно быстрее, иначе буфер будет заполнен, приём данных от сервера остановится и
соединение может быть потеряно. Это не проблема библиотеки -- при работе под Windows, даже если приложение
читает данные медленно, соединение не теряется. В настоящее время, допустимый размер буфера 256 Кб - 256 Мб.
На самом деле, библиотека создает два буфера заданного размера. Буферы кольцевые: если достигнут конец
буфера, то данные будут записаны в начало, если начало уже прочитано приложением. При быстрой работе
приложения и медленной работе сети, переполнение буферов не происходит.
- error -- возвращаемый код ошибки (отрицательное число), 0 -- успех.
результат: указатель на параметры соединения, 0 -- ошибка
______________
void session (void *params, void *buffer)
получить session_id и master_secret ранее открытой (и еще не закрытой!) сессии
- params -- указатель на параметры соединения ранее открытой сессии
- buffer -- адрес памяти, куда будет записан результат (81 байт минимум). Это можно использовать для открытия
следующей сессии с тем же сервером (функция open, параметр session), чтобы повторно не вычислять RSA
(алгоритм RSA работает медленно).
______________
void close (void **params)
закрыть сессию, освободить память
- params -- указатель на параметры соединения. Будет присвоено значение 0.
______________
int send (void *params, void *buffer, int size)
отправить данные
- params -- указатель на параметры соединения
- buffer -- указатель на данные
- size -- размер данных
результат: 0 -- успех, иначе код ошибки
______________
int recv (void *params, void *buffer, int size)
получить данные
- params -- указатель на параметры соединения
- buffer -- указатель на буфер для данных
- size -- размер буфера
результат:
>= 0 -- количество записанных в буфер байтов.
-17 -- сервер завершил передачу данных и закрыл сессию. После этого необходимо вызвать close,
чтобы освободить память.
< 0 (!= -17) -- код ошибки.
______________
Общий порядок вызовов:
open
session (необязательно)
send
recv
close
Cоглашение вызовов stdcall.
Рекомендуемый минимальный размер стэка приложения 256 Кб.
03-nov-2017
До перерыва, я всё же сделал одно небольшое, но важное улучшение. Я переделал алгоритм RSA (изменил форму представления длинных чисел и сделал предварительные вычисления). Теперь RSA работает в 7 раз быстрее. На Core i7 время работы алгоритма сократилось с 2250 мс до 320 мс. Приложению требуется дополнительно 64 Кб стэка для хранения результатов предварительных вычислений.
- Attachments
-
-
TLSv0.21.zip (62.76 KiB)Downloaded 312 times
-
Last edited by akron1 on Fri Nov 03, 2017 5:49 pm, edited 1 time in total.