LINUX.ORG.RU

Linux C TLS client/server есть информация?

 


0

2

Здравствуйте, коллеги!

Понадобилось реализовать шифрованное соединение клиент/сервер.

Разумеется, первым делом в google, но «достоверной» информации пока не нашел.

Есть примеры, но или не полные, или с ошибками.

Когда всю эту тему не очень понимаешь, то хотелось бы рабочие примеры.

Вот к примеру: https://aticleworld.com/ssl-server-client-using-openssl-in-c/

Даже компиллируется! Достижение!

Однако, я так и не нашел где клиент подсасывает сертификаты.

Соединение выходит не защищенным.

Ну и вопрос к гуру: как происходит шифрование? Пакетным или потоковым способом?

Буду очень рад рабочим примерам.


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

firkax ★★★★★
()

шифрованное соединение клиент/сервер

Всё просто:

  • сервер - nginx + letsencrypt
  • клиент - любой http-клиент, с подержкой tls

Upd. Проглядел буковку Си, это тебе кодить надо? Такое себе спрашивать на форуме про это.

vvn_black ★★★★★
()
Последнее исправление: vvn_black (всего исправлений: 2)
Ответ на: комментарий от alex0x08

я откомпилял, сгенерировал сертификаты. Запустил. Все работает!

На первый взгляд, можно скопипастить ОГРОМНЫЕ куски кода по инициализации и сосредоточится на преме-отправке пакетов

Если смотреть код клиента, то можно скопипастить и обернуть для удобства ВСЕ до SSL_write

HighMan
() автор топика
Последнее исправление: HighMan (всего исправлений: 2)
Ответ на: комментарий от C

Забавно.

Смотрю разные примеры и в восторге от goto!

Вроде, считается совсем плохим тоном использовать подобные конструкции в C/C++

И еще я пока не могу понять SSL_write(ssl, buffer, (int) len)) как добраться до fd? Что бы, например, использовать poll.

HighMan
() автор топика
Ответ на: комментарий от HighMan

И еще я пока не могу понять SSL_write(ssl, buffer, (int) len)) как добраться до fd? Что бы, например, использовать poll.

int SSL_get_fd(const SSL *ssl);

int SSL_get_rfd(const SSL *ssl);

int SSL_get_wfd(const SSL *ssl);

HighMan
() автор топика
Последнее исправление: HighMan (всего исправлений: 1)

Однако, я так и не нашел где клиент подсасывает сертификаты.

У TLS-клиентов как правило нет своих сертификатов и они не отправляют их серверу. В основном это TLS-сервер отправляет клиенту свой сертификат, чтобы клиент убедился что сервер именно тот за кого себя выдает.

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

dvetutnev
()
Ответ на: комментарий от HighMan

Вроде, считается совсем плохим тоном использовать подобные конструкции в C/C++

дурным тоном считается неумение пользоваться goto. это очень хороший и удобный инструмент для использования в критических для производительности частях кода.

ergo ★★★
()
Ответ на: комментарий от ergo

это очень хороший и удобный инструмент для использования в критических для производительности частях кода.

А можно пример такого использования? Хоть один.

alex0x08 ★★★
()
Ответ на: комментарий от alex0x08

легко. как пример, реализация регэкспов в го

https://github.com/golang/go/blob/master/src/regexp/backtrack.go

я сам пользуюсь goto в критических кусках (особенно в stackless реализациях)

надеюсь не нужно уточнять, что использование goto это про алгоритмы, а не про ЯП.

ergo ★★★
()
Последнее исправление: ergo (всего исправлений: 1)
Ответ на: комментарий от ergo

Выглядит как костыль:

	// Optimization: rather than push and pop,
		// code that is going to Push and continue
		// the loop simply updates ip, p, and arg
		// and jumps to CheckAndLoop. We have to
		// do the ShouldVisit check that Push
		// would have, but we avoid the stack
		// manipulation.
		goto Skip
	CheckAndLoop:
		if !b.shouldVisit(pc, pos) {
			continue
		}
	Skip:

Те это получается цикл, в котором первый шаг - переход по метке. А изнутри блока идет переход на этот CheckAndLoop: лишь ради единственного вызова функции.

Причем там switch-case блок где каждый case завершается goto:

case syntax.InstNop:
			pc = inst.Out
			goto CheckAndLoop

Вообщем пример откровенно не очень.

alex0x08 ★★★
()
Ответ на: комментарий от alex0x08

Те это получается цикл, в котором первый шаг - переход по метке. А изнутри блока идет переход на этот CheckAndLoop: лишь ради единственного вызова функции.

без оценки влияния такой оптимизации я бы был осторожен в выводах. вот прям даже бы не рекомендовал делать выводы без погружения в алгоритм и только лишь глядя на переход «ради лишь единственного вызова функции».

ну и я привел «хоть один» пример, прям за минуту беглого поиска в локальных репах. не было целью найти идеальный ибо это очень зависит от алгоритма и какой прирост дает использование goto в конкретном месте. захочешь разобраться в теме, найдешь время и силы погрузиться в нее.

ergo ★★★
()
Последнее исправление: ergo (всего исправлений: 2)
Ответ на: комментарий от alex0x08

А можно пример такого использования? Хоть один.

Для очистки ресурсов при альтернативном завершении функции.

auto func()
{
  A* a = createA();
  if (!a) {
    //set error
    return;
  }
  B* b = createB();
  if (!b) {
    goto clearA;
  }
  C* c = createC();
  if (!c) {
    goto clearB;
  }

  process(a, b, c);

clearC:
  releaseC(c);

clearB:
  releaseB(b);

clearA:
  releaseA(a);
}

Но это больше для Си актуально, для С++ есть RAII и деструкторы.

dvetutnev
()
Последнее исправление: dvetutnev (всего исправлений: 1)
Ответ на: комментарий от alex0x08

В очистке b и a, чтобы она выполнялась в одном месте. С двумя объектами goto не нужен, с тремя и более очистка (при ошибках) на ветвлениях получается шибко развесистой. Но, повторюсь, для C++ оно не актуально, там RAII есть и какие-то дополнительные приседания с очисткой не требуются.

dvetutnev
()
Ответ на: комментарий от firkax

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

Если тебе нужно задействовать семафор в новом приложении на Си, то ты не изучаешь месяцами механизмы внутриядерных блокировок и десятки плохо документированных системных вызовов (привет io_uring). Но для OpenSSL неадекватная криптодокументация является нормой. Та же история, например, с Git.

Придётся изучать общую теорию современных шифров, маны к openssl, другие статьи про openssl и местами его исходники

Зачем мне знать про современные шифры, если мне нужно просто задействовать готовую реализацию TLS с готовыми ключами/сертификатами? Примечательно, что я таки изучал «современные шифры», но API OpenSSL для меня по прежнему выглядит трешово.

byko3y ★★★★
()
Последнее исправление: byko3y (всего исправлений: 1)
Ответ на: комментарий от byko3y

Если тебе нужно задействовать семафор в новом приложении на Си, то ты не изучаешь месяцами механизмы внутриядерных блокировок

Зачем мне знать про современные шифры, если мне нужно просто задействовать готовую реализацию TLS с готовыми ключами/сертификатами?

У автора среди прочего был вопрос «как происходит шифрование?» - это было к нему.

API OpenSSL для меня по прежнему выглядит трешово

Согласен.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)
Ответ на: комментарий от byko3y

Зачем мне знать про современные шифры, если мне нужно просто задействовать готовую реализацию TLS с готовыми ключами/сертификатами?

Тут в соседнем треде мне сказали что я сам придумал «key derivation» а сам ТС решил что будет использовать «частично генеренные пароли» для защиты своих поделок.

Поэтому увы но нет, все что касается криптографии требует изучения матчасти.

alex0x08 ★★★
()
Ответ на: комментарий от firkax

У автора среди прочего был вопрос «как происходит шифрование?» - это было к нему.

Вопрос был:

Ну и вопрос к гуру: как происходит шифрование? Пакетным или потоковым способом?

То есть, автора не волнует, как OpenSSL внутри себя делает шифрование. На самом деле автора волнуют вопросы потоков BIO, выполняющими роль универсально непонятного интерфейса передачи данных в OpenSSL.

byko3y ★★★★
()
Ответ на: комментарий от alex0x08

Если тебе нужно админить ФС, менять размеры разделов, создавать массивы, то тебе нужно знать соответствующие подробности. Если ты эитм не занимаешься, то не нужно. Мне, как тупому пользователю OpenSSL, не интересно знать, использует ли он эфемерный ключ или нет.

byko3y ★★★★
()
Ответ на: комментарий от byko3y

Мне, как тупому пользователю OpenSSL, не интересно знать,

Да да, конечно.

Чем больше будет таких «пользователей», тем больше будет у меня работы )

Так что долгой жизни и крепкого здоровья. И самое главное: никогда и ни за что не надо думать и «интересоваться», пусть другие думают (например я да).

alex0x08 ★★★
()
Ответ на: комментарий от byko3y

Зачем мне знать про современные шифры, если мне нужно просто задействовать готовую реализацию TLS с готовыми ключами/сертификатами? Примечательно, что я таки изучал «современные шифры», но API OpenSSL для меня по прежнему выглядит трешово.

Совершенно верно.

Если нужно доехать на машине из пункта «А» в пункт «Б», то совершенно не обязательно глубоко разбираться в устройстве автомобиля.

Тему я поднимал довольно давно, но тем не менее ее не забросил и продолжаю рыть на тему TLS/SSL.

Кое что начало получаться, но… Возникает куча вопросов.

Сейчас столкнулся с вылетом сервера (С++) если handshake закончилось успешно, пошло какое-то общение между клиентом и сервером и если не корректно вырубить клиента, то сервер падает.

Т.е. если слиент не завершил корректно соединение через shutdown, то сервер получает пакет SSL_read(ssl, data, 1024) нулевой длинны и падает.

Не могу понять как правильно отлавливать эту неприятность.

HighMan
() автор топика
Ответ на: комментарий от HighMan

Смотрю разные примеры и в восторге от goto! Вроде, считается совсем плохим тоном использовать подобные конструкции в C/C++

Плохим тоном это считается разве что у преподов в провинциальных шарагах, которые реального кода на Си никогда не видели.

Без goto, в Си ты будешь городить лапшу из вложенных ифов, в особенности при инициализации структур и обработке ошибок.

lovesan ★★
()