SSL + ГОСТ

338 views
Skip to first unread message

Alexander Malev

unread,
Sep 2, 2014, 11:12:05 AM9/2/14
to erlang-...@googlegroups.com
Столкнулся с задачей зашифровывать соединение по алгоритму ГОСТ который реализован в openssl начиная с версии 1.0.0.
Сгенерировал ключ+сертификат. Потестил на чистом openssl - работает. Предварительно нужно было в конфиге заставить openssl грузить engine libgost.so.

Прямым подсовыванием pem в ssl:listen, первое обо что спотыкается это парсинг сертификата посредством public_key(укладка другая/неизвестные идентификаторы).
Одним из следующих преткновений предполагаю, что будет не загруженный engine.

Кто копал в этом направлении и добился каких-либо результатов?

Danil A. Zagoskin

unread,
Sep 2, 2014, 1:30:51 PM9/2/14
to erlang-...@googlegroups.com
Начать следует с того, как реализована функция ssl:cipher_suites().

Как минимум tls_v1:all_suites имеет захардкоженный список наборов шифров.

Для реализации ГОСТ (дялее для определенности TLS_GOSTR341001_WITH_28147_CNT_IMIT) нужно поддержать (вставить нужные названия):
  - key exchange algorithm GOST2001
  - bulk encryption algorithm GOST89
  - message authentication code GOST89

При этом, если я не ошибаюсь, львиная доля key exchange пишется на эрланге (с использованием либы только для подсчета хешей).

То есть, за неделю сделать такое будет очень проблематично. Я рекомендую посмотреть в сторону вынесения криптухи в соседний демон типа haproxy или (о ужас) некрофилии типа https://github.com/processone/exmpp/blob/master/c_src/exmpp_tls.c



--
Вы получили это сообщение, поскольку подписаны на группу Erlang по-русски.

Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес erlang-russia...@googlegroups.com.
Чтобы добавлять сообщения в эту группу, отправьте письмо по адресу erlang-...@googlegroups.com.
Настройки подписки и доставки писем: https://groups.google.com/d/optout.

Alexander Malev

unread,
Sep 5, 2014, 10:14:26 AM9/5/14
to
Спасибо за ответ.

Сейчас уперся в crypto:sign который должен позвать что-то вроде gost_sign_nif, который в свою очередь требует знаний API openssl и erl_interface.
Ещё по пути достаточно магическим показалось:
ssl_cipher:filter(DerCert, Ciphers) ->
    OtpCert = public_key:pkix_decode_cert(DerCert, otp),
    SigAlg = OtpCert#'OTPCertificate'.signatureAlgorithm,
    PubKeyInfo = OtpCert#'OTPCertificate'.tbsCertificate#'OTPTBSCertificate'.subjectPublicKeyInfo,
    PubKeyAlg = PubKeyInfo#'OTPSubjectPublicKeyInfo'.algorithm,

    Ciphers1 =
case ssl_certificate:public_key_type(PubKeyAlg#'PublicKeyAlgorithm'.algorithm) of
   rsa ->
filter_keyuse(OtpCert, ((Ciphers -- dsa_signed_suites()) -- ec_keyed_suites()) -- ecdh_suites(),
     rsa_suites(), dhe_rsa_suites() ++ ecdhe_rsa_suites());
   dsa ->
(Ciphers -- rsa_keyed_suites()) -- ec_keyed_suites();
   ec ->
filter_keyuse(OtpCert, (Ciphers -- rsa_keyed_suites()) -- dsa_signed_suites(),
     [], ecdhe_ecdsa_suites());
    gostR3410_2001 ->
%%         TODO gostR3410_2001
filter_keyuse(OtpCert, (Ciphers -- rsa_keyed_suites())
                                      -- ec_keyed_suites(),
     [], gost_suites())
end,

    case public_key:pkix_sign_types(SigAlg#'SignatureAlgorithm'.algorithm) of
{_, rsa} ->
   Ciphers1 -- ecdsa_signed_suites();
{_, dsa} ->
   Ciphers1;
{_, ecdsa} ->
   Ciphers1 -- rsa_signed_suites();
{_, gostR3410_2001} ->
%%     TODO {_, gostR3410_2001}
    (Ciphers1 -- ecdsa_signed_suites()) -- rsa_signed_suites()
    end.
В результате сертификат клиенту отдаёт, но не может хэндшейк доделать

Недели да, не хватит (:
Reply all
Reply to author
Forward
0 new messages