OpenSSL FIPS_mode_set не работает в библиотеке криптографии Python - PullRequest
3 голосов
/ 04 октября 2019

Согласно документации библиотеки криптографии Python [1], можно построить собственное колесо криптографии со статически связанной OpenSSL. Я попытался сделать это с помощью установки OpenSSL, созданной с использованием объектного модуля FIPS, и смог успешно построить колесо, но обнаружил, что у него нет функции FIPS (невозможно установить FIPS_mode_set = 1).

Я создалDockerfile, который может воспроизвести тот же результат. Код Python в конце должен показывать «1» и «OpenSSL 1.0.2t-fips 10 сентября 2019 года», но вместо этого показывать «0» и «OpenSSL 1.0.2t 10 сентября 2019 года» (без обозначения -fips).

Меня поражает то, что когда я вызываю openssl version CLI, который я построил, он правильно показывает версию с суффиксом -fips. Потому что из-за этого я предполагаю, что где-то ошибся в построении криптографии.

Оцените любую помощь здесь!

FROM centos

# Install build dependencies
RUN yum groupinstall -y  "Development Tools" && \
    yum install -y python-devel libffi-devel

# Install Python dependencies
RUN curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && \
    python get-pip.py && \
    pip install virtualenv setuptools wheel pip

# Build Fips object module
RUN curl -O https://www.openssl.org/source/openssl-fips-2.0.16.tar.gz && \
    tar xvf openssl-fips-2.0.16.tar.gz && \
    cd openssl-fips-2.0.16 && \
    ./config && \
    make && \
    make install

# Build OpenSSL
RUN curl -O https://www.openssl.org/source/openssl-1.0.2t.tar.gz && \
    tar xvf openssl-1.0.2t.tar.gz && \
    cd /openssl-1.0.2t && \
    ./config fips no-shared -fPIC --prefix=/openssl-1.0.2t/openssl && \
    make depend && \
    make && \
    make install_sw

# Build cryptography
RUN CFLAGS="-I/openssl-1.0.2t/openssl/include" LDFLAGS="-L/openssl-1.0.2t/openssl/lib" pip wheel --no-cache --no-binary :all: cryptography && \
    pip install cryptography*.whl

# Test if fips is enabled
RUN python -c "\
from cryptography.hazmat.backends.openssl.backend import backend;\
print backend._lib.FIPS_mode_set(1);\
print ''.join([backend._lib.OPENSSL_VERSION_TEXT[i] for i in range(30)])"

[1] https://cryptography.io/en/latest/installation/#static-wheels

РЕДАКТИРОВАТЬ: Добавив -DOPENSSL_FIPS в криптографическую сборку, я смог сделать вывод OPENSSL_VERSION_TEXT равным OpenSSL 1.0.2t-fips 10 Sep 20, но вывод FIPS_mode_set (1) по-прежнему равен 0.

РЕДАКТИРОВАТЬ 2: Использование ERR_get_error() показывает следующее:

>>> print backend._lib.FIPS_mode_set(1)
0
>>> print backend._lib.ERR_get_error()
755413103

Когда я вставляю это в openssl errstr, я получаю:

openssl errstr 755413103
error:755413103:lib(85):func(1043):reason(259)

Согласно некоторым поискам Google, это означает, что отпечаток пальца не совпадает (FIPS_R_FINGERPRINT_DOES_NOT_MATCH). Не уверен, куда идти отсюда.

1 Ответ

1 голос
/ 09 октября 2019

1. Общее

Прежде всего, я хочу упомянуть, что хотя я понимаю причины, я не полностью согласен с видением Криптография ( [Криптография]: Установка - СтатическаяКолеса ). Совместно используемые библиотеки существуют десятилетиями и доказали свое превосходство. Не говоря уже о том, что Python поставляет 2 (стандартные) модули ( _ssl и _hashlib ), которые динамически ссылка на OpenSSL (что бы это ни было в системе). В качестве примечания, на Win модули 2 Python также используются для статической ссылки на OpenSSL , но начинаются с v 3.7 , они больше не делают. Назад к Nix : 2 Версии OpenSSL загружаются в один и тот же ( Python ) процесс. Это не вредит, но выглядит смешно. И так как сегодня ( 191009 ), есть куча .whl с для v2.7 и v3.4 ,но ничего для довольно приличного ( Python ) окружения:

Img0

Я помню похожую ситуацию некоторое время назад: помимо 2стандартные модули M2Crypto также использовались. В этой ситуации (мы поставили Python полностью), 2 конкретных ( FIPS способны) OpenSSL ( динамический ) lib *Также были отправлены 1065 * s, и все модули Python связаны с ними. Он работал в различных ( настольных ) средах (из которых многие "экзотические"):

  • CPU архитектуры ( LE *)1076 * / BE ): x86 , AMD64 , IA64 , SPARC , PPC , zSeries
  • ОС es (с несколькими версиями): Win , Lnx ( RH , CentOS , OEL , SuSE , Xen , Ubuntu ), Solaris , AIX , HP-UX (и в качестве личного упражнения я добавил OSX )

[OpenSSL]: UserGuide-2.0.pdf - Руководство пользователя для объектного модуля OpenSSL FIPS v2.0 (ссылка из [OpenSSL]: FIPS-140 в случае изменения URL ) содержитвсе необходимые детали.

Прежде чем идти дальше, вот несколько терминов, которые я собираюсь использовать в этом посте:

  • FOM - FIPS объектный модуль (fipscanister.o )
  • FOME - исполняемый файл ( ELF ( PE на Win )), который FOM был связан в . Имейте в виду, что это может быть либо исполняемый файл сам по себе , либо .so ( .dll ). Кроме того, если он включен в статическую библиотеку ( .a ), он не связан (просто заархивирован). В качестве примечания, когда OpenSSL собран совместно, FOME равен libcrypto.so. *, тогда как при статической сборке (как в этом случае) этоисполняемый файл, который связывается с libcrypto.a (например, openssl исполняемый файл)

FOM поставляется поверх OpenSSL (и, вероятно, других таких поставщиков криптографии, как LibreSSL , WolfSSL ,), и это предназначено для усиления безопасности (согласно стандартам NIST ), ограничиваянекоторые функции, которые в противном случае были бы доступны. Одним из таких примеров является использование хеша md5 , который считается слабым (я уверен, что sha1 будет следовать в следующей версии обудет выпущен).
Вот (очень упрощенная) версия того, что происходит (во время выполнения):

  1. FIPS включен режим:
    1. Проверьте,дополнительные ограничения соблюдены:
      1. Да: продолжить (с функциональностью по умолчанию)
      2. Нет: возврат с ошибкой
  2. FIPS режим выключен:
    1. Откат к функциональности по умолчанию

Часть # 1.1. является самопроверкой. Он состоит из:

  • Вычисление FOME подписи
  • Сравнение со значением (которое также было сохранено в FOME )

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

  1. Все источники FOME + FOM скомпилированы (в объектные файлы)
  2. Они связаны вместе (в FOME ). Это когда нормальная сборка заканчивается
  3. Считается FOME подпись
    1. Элементы из # 1. + fips_premain.o связаны с (настоящим, а не .dll ) исполняемым файлом ( FPD )
    2. FPD вызывается против FOME ( # 1. ). Он читает раздел FOME .rodata и вычисляет его sha1 хэш. Обратите внимание, что игнорирует 41 зону байтов (пробивает отверстие) , расположенную по определенному адресу
  4. # 3.1. повторяется, но на этот раз fips_premain.o было перекомпилировано, чтобы также включить хэш из предыдущего шага. Теперь становится понятным пробитое отверстие из предыдущего шага, это место, куда идет подпись: (длина ша хеш ( 40 ) + нуль ). Это последний FOME

Примечание: при Win все происходит немного иначе.

Мне удалось воспроизвести проблему. Я собираюсь начать с тестового сценария.

code00.py :

#!/usr/bin/env python3

import sys
from cryptography.hazmat.backends.openssl.backend import backend
import cffi


def main():
    ffi = cffi.FFI()
    lib = backend._lib
    fmt = "OpenSSL version: {0:s}\nFIPS_mode(): {1:d}\nFIPS_mode_set(1): {2:d}\nFIPS_mode(): {3:d}"
    print(fmt.format(ffi.string(lib.OPENSSL_VERSION_TEXT).decode(),
                    lib.FIPS_mode(), lib.FIPS_mode_set(1), lib.FIPS_mode()))
    err = lib.ERR_get_error()
    if err:
        err_fmt = "error:[{0:d}]:[{1:s}]:[{2:s}]:[{3:s}]"
        print(err_fmt.format(
                err,
                ffi.string(lib.ERR_lib_error_string(err)).decode(),
                ffi.string(lib.ERR_func_error_string(err)).decode(),
                ffi.string(lib.ERR_reason_error_string(err)).decode()
        ))
    else:
        print("Success !!!")


if __name__ == "__main__":
    print("Python {0:s} {1:d}bit on {2:s}\n".format(" ".join(item.strip() for item in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform))
    main()
    print("\nDone.")

2. Настройка

Я уже собрал FOM и FIPS с поддержкой OpenSSL (аналогично вашему, но я настроил их пути). Переменная $ {FIPSDIR} использовалась при построении FOM и OpenSSL .

[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q058228435]> ~/sopr.sh
*** Set shorter prompt to better fit when pasted in StackOverflow (or other) pages ***

[064bit-prompt]> uname -a
Linux cfati-ubtu16x64-0 4.15.0-65-generic #74~16.04.1-Ubuntu SMP Wed Sep 18 09:51:44 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
[064bit-prompt]> cat /etc/lsb-release | grep DESCR
DISTRIB_DESCRIPTION="Ubuntu 16.04.6 LTS"
[064bit-prompt]> gcc --version | grep gcc
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609
[064bit-prompt]>
[064bit-prompt]> echo ${FIPSDIR}
/home/cfati/Work/Dev/Tools/zzz_Build/OpenSSL/int/openssl-fips-2.0.16
[064bit-prompt]> tree ${FIPSDIR}
/home/cfati/Work/Dev/Tools/zzz_Build/OpenSSL/int/openssl-fips-2.0.16
├── bin
│   ├── fipsld
│   └── fips_standalone_sha1
├── include
│   └── openssl
│       ├── aes.h
│       ├── bn.h
│       ├── buffer.h
│       ├── cmac.h
│       ├── crypto.h
│       ├── des.h
│       ├── des_old.h
│       ├── dh.h
│       ├── dsa.h
│       ├── ebcdic.h
│       ├── ecdh.h
│       ├── ecdsa.h
│       ├── ec.h
│       ├── e_os2.h
│       ├── evp.h
│       ├── fips.h
│       ├── fips_rand.h
│       ├── fipssyms.h
│       ├── hmac.h
│       ├── modes.h
│       ├── opensslconf.h
│       ├── opensslv.h
│       ├── ossl_typ.h
│       ├── rsa.h
│       ├── sha.h
│       └── symhacks.h
└── lib
    ├── fipscanister.o
    ├── fipscanister.o.sha1
    ├── fips_premain.c
    └── fips_premain.c.sha1

4 directories, 32 files
[064bit-prompt]>
[064bit-prompt]> echo ${OPENSSL_DIR}
/home/cfati/Work/Dev/Tools/openssl-1.0.2t-fips-2.0.16-static
[064bit-prompt]> tree ${OPENSSL_DIR}/bin ${OPENSSL_DIR}/lib
/home/cfati/Work/Dev/Tools/openssl-1.0.2t-fips-2.0.16-static/bin
├── c_rehash
└── openssl
/home/cfati/Work/Dev/Tools/openssl-1.0.2t-fips-2.0.16-static/lib
├── engines
├── libcrypto.a
├── libssl.a
└── pkgconfig
    ├── libcrypto.pc
    ├── libssl.pc
    └── openssl.pc

2 directories, 7 files
[064bit-prompt]>
[064bit-prompt]> ldd ${OPENSSL_DIR}/bin/openssl
    linux-vdso.so.1 =>  (0x00007ffeec045000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f12c19c2000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f12c15f8000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f12c1bc6000)
[064bit-prompt]>
[064bit-prompt]> ${OPENSSL_DIR}/bin/openssl version
OpenSSL 1.0.2t-fips  10 Sep 2019
[064bit-prompt]> ${OPENSSL_DIR}/bin/openssl sha1 ./code00.py
SHA1(./code00.py)= ff122260b025103dbc03316e3d3e26cd683e7a12
[064bit-prompt]> ${OPENSSL_DIR}/bin/openssl md5 ./code00.py
MD5(./code00.py)= eac85e46734260c1bfcceb89d6a3bd32
[064bit-prompt]> OPENSSL_FIPS=1 ${OPENSSL_DIR}/bin/openssl sha1 ./code00.py
SHA1(./code00.py)= ff122260b025103dbc03316e3d3e26cd683e7a12
[064bit-prompt]> OPENSSL_FIPS=1 ${OPENSSL_DIR}/bin/openssl md5 ./code00.py
Error setting digest md5
140584610875032:error:060A80A3:digital envelope routines:FIPS_DIGESTINIT:disabled for fips:fips_md.c:180:

3. Криптография модуль

[064bit-prompt]> ls
code00.py  cryptography-2.7.tar.gz
[064bit-prompt]> mkdir build
[064bit-prompt]> cd build
[064bit-prompt]>
[064bit-prompt]> CFLAGS="-I${OPENSSL_DIR}/include -DOPENSSL_FIPS=1" LDFLAGS="-L${OPENSSL_DIR}/lib" python3 -m pip wheel --no-cache --no-binary :all: ../cryptography-2.7.tar.gz
Processing /home/cfati/Work/Dev/StackOverflow/q058228435/cryptography-2.7.tar.gz
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
    Preparing wheel metadata ... done
Collecting asn1crypto>=0.21.0 (from cryptography==2.7)
  Downloading https://files.pythonhosted.org/packages/d1/e2/c518f2bc5805668803ebf0659628b0e9d77ca981308c7e9e5564b30b8337/asn1crypto-1.0.1.tar.gz (115kB)
     |████████████████████████████████| 122kB 801kB/s
Collecting cffi!=1.11.3,>=1.8 (from cryptography==2.7)
  Downloading https://files.pythonhosted.org/packages/93/1a/ab8c62b5838722f29f3daffcc8d4bd61844aa9b5f437341cc890ceee483b/cffi-1.12.3.tar.gz (456kB)
     |████████████████████████████████| 460kB 1.8MB/s
Collecting six>=1.4.1 (from cryptography==2.7)
  Downloading https://files.pythonhosted.org/packages/dd/bf/4138e7bfb757de47d1f4b6994648ec67a51efe58fa907c1e11e350cddfca/six-1.12.0.tar.gz
Collecting pycparser (from cffi!=1.11.3,>=1.8->cryptography==2.7)
  Downloading https://files.pythonhosted.org/packages/68/9e/49196946aee219aead1290e00d1e7fdeab8567783e83e1b9ab5585e6206a/pycparser-2.19.tar.gz (158kB)
     |████████████████████████████████| 163kB 4.5MB/s
Building wheels for collected packages: cryptography, asn1crypto, cffi, six, pycparser
  Building wheel for cryptography (PEP 517) ... done
  Stored in directory: /home/cfati/Work/Dev/StackOverflow/q058228435/build
  Building wheel for asn1crypto (setup.py) ... done
  Stored in directory: /home/cfati/Work/Dev/StackOverflow/q058228435/build
  Building wheel for cffi (setup.py) ... done
  Stored in directory: /home/cfati/Work/Dev/StackOverflow/q058228435/build
  Building wheel for six (setup.py) ... done
  Stored in directory: /home/cfati/Work/Dev/StackOverflow/q058228435/build
  Building wheel for pycparser (setup.py) ... done
  Stored in directory: /home/cfati/Work/Dev/StackOverflow/q058228435/build
Successfully built cryptography asn1crypto cffi six pycparser
WARNING: You are using pip version 19.1.1, however version 19.2.3 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
[064bit-prompt]>
[064bit-prompt]> ls
asn1crypto-1.0.1-py3-none-any.whl        cryptography-2.7-cp35-cp35m-linux_x86_64.whl  six-1.12.0-py2.py3-none-any.whl
cffi-1.12.3-cp35-cp35m-linux_x86_64.whl  pycparser-2.19-py2.py3-none-any.whl
[064bit-prompt]>
[064bit-prompt]> for f in $(ls *.whl); do unzip ${f} > /dev/null; done
[064bit-prompt]> ls
asn1crypto                         cffi-1.12.3-cp35-cp35m-linux_x86_64.whl        cryptography-2.7-cp35-cp35m-linux_x86_64.whl  pycparser-2.19-py2.py3-none-any.whl
asn1crypto-1.0.1.dist-info         cffi-1.12.3.dist-info                          cryptography-2.7.dist-info                    six-1.12.0.dist-info
asn1crypto-1.0.1-py3-none-any.whl  _cffi_backend.cpython-35m-x86_64-linux-gnu.so  pycparser                                     six-1.12.0-py2.py3-none-any.whl
cffi                               cryptography                                   pycparser-2.19.dist-info                      six.py
[064bit-prompt]> PYTHONPATH=.:${PYTHONPATH} python3 ../code00.py
Python 3.5.2 (default, Jul 10 2019, 11:58:48) [GCC 5.4.0 20160609] 64bit on linux

OpenSSL version: OpenSSL 1.0.2t-fips  10 Sep 2019
FIPS_mode(): 0
FIPS_mode_set(1): 0
FIPS_mode(): 0
error:[755413103]:[FIPS routines]:[FIPS_check_incore_fingerprint]:[fingerprint does not match]

Done.

Как видно, я в значительной степени там, где вы находитесь.

4. Более глубокое погружение

После долгих (и некоторых может показаться болезненными) часов отладки, испытаний ... я пришел к выводу. Учитывая, что:

  • Подделка чего-либо из FOM (содержимое $ {FIPSDIR} ), одиночка не будет квалифицироваться как FIPS подтверждено . Честно говоря, этого тоже не происходит, поскольку есть конкретные инструкции, что при сборке FOM только sys admin должен копировать артефакты в безопасном месте ...., бла, блаблаМне это кажется параноидальным, но это факты. Как примечание, еще в 2013 году, когда мы 1 st вступили в контакт с FIPS (вероятно, для предотвращения любой возможной атаки (например, MITM )), FOM источники CD было отправлено из США в ROU :)))
  • По умолчанию Python версия построена статически (снова :)), что означает, что $ {PYTHONCORE} (интерпретатор Python ) находится в исполняемом файле python , а не в .so ( libpython * .so *), который может быть связан с (и который исполняемый файл python делает в случае общих сборок)
  • Криптография Для модуля расширения _openssl ( _openssl.abi * .so ) нужны символы из $ {PYTHONCORE} (например, PyLong_FromLong ), но это OK , поскольку в данный момент он будет загружен в процесс ( Python ) (запущенный из вышеупомянутого исполняемого файла), оннайдет их (это обычный рractice на Nix )
  • Шаг сборки # 3.2. : исполняемый файл ( FPD - который должен выполняться) не выполняетсяне найти символы, поэтому он не может

Это тупик (вне зависимости от того, какая комната выходит из одного ограничения, закрыта другими), поэтому ЭТО ПРОСТО НЕ МОЖЕТ БЫТЬ СДЕЛАНО !!! (по крайней мере, на данный момент). Период! X (

5. Альтернатива

Я собирался предложить это как элегантную альтернативу (включая OpenSSL .so s (с любым ( .so ) клиент с rpath , установленным на "там") в .whl , рядом с _openssl.abi3.so , который связываетдля них), но, по-видимому, это единственный путь (который я нашел, по крайней мере).

Шаг 1 st состоит в создании общего OpenSSL версия ( FOME будет libcrypto.so. *).

[064bit-prompt]> ls
code00.py  cryptography-2.7.tar.gz
[064bit-prompt]> export OPENSSL_DIR=/home/cfati/Work/Dev/Tools/openssl-1.0.2t-fips-2.0.16
[064bit-prompt]> ldd ${OPENSSL_DIR}/bin/openssl
        linux-vdso.so.1 =>  (0x00007ffe62faf000)
        libssl.so.1.0.0 => /home/cfati/Work/Dev/Tools/openssl-1.0.2t-fips-2.0.16/lib/libssl.so.1.0.0 (0x00007fe33c06f000)
        libcrypto.so.1.0.0 => /home/cfati/Work/Dev/Tools/openssl-1.0.2t-fips-2.0.16/lib/libcrypto.so.1.0.0 (0x00007fe33bb92000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe33b7c8000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fe33b5c4000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fe33c2e3000)
[064bit-prompt]>
[064bit-prompt]> ${OPENSSL_DIR}/bin/openssl version
OpenSSL 1.0.2t-fips  10 Sep 2019
[064bit-prompt]> ${OPENSSL_DIR}/bin/openssl md5 ./code00.py
MD5(./code00.py)= eac85e46734260c1bfcceb89d6a3bd32
[064bit-prompt]> OPENSSL_FIPS=1 ${OPENSSL_DIR}/bin/openssl md5 ./code00.py
Error setting digest md5
139796140275352:error:060A80A3:digital envelope routines:FIPS_DIGESTINIT:disabled for fips:fips_md.c:180

После очередного сеанса глубокого погружения (множество неудачных попыток)попыток), я смог заставить его работать. Однако предпринял много действий:

  • Ручные вмешательства
  • Взломы
  • (Хромой) обходные пути ( gainarii )

Боюсь, что если бы я все это здесь поместил, он бы значительно превысил 30K char s limit ( [SE.Meta]: Зная свои пределы: какова максимальная длина названия вопроса,post, image и использованные ссылки? ).

Однако я опубликовал .whl на [GitHub]: CristiFati / Prebuilt-Binaries - (master) Prebuilt-Binaries / Криптография / v2.7 / OpenSSL-1.0.2t-fips-2.0.16 . Пока это только для Python 3.5 ( 64bit ), так как это версия по умолчанию, которая устанавливается на Ubuntu 16 . Если вы используете другую (более новую) версию, просто дайте мне знать, и я ее получу (возможно, соберу сам), и соберу .whl для этой версии (я все равно собираюсь это сделать)).

После замены оригинального .whl на созданный мной:

[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q058228435/build]> ll
total 2936
drwxrwxr-x 2 cfati cfati    4096 Oct  9 21:40 .
drwxrwxr-x 4 cfati cfati    4096 Oct  9 21:28 ..
-rw-rw-r-- 1 cfati cfati  108067 Oct  9 08:43 asn1crypto-1.0.1-py3-none-any.whl
-rw-rw-r-- 1 cfati cfati  318045 Oct  9 08:43 cffi-1.12.3-cp35-cp35m-linux_x86_64.whl
-rw-rw-r-- 1 cfati cfati 2438739 Oct  9 21:40 cryptography-2.7-cp35-cp35m-linux_x86_64.whl
-rw-rw-r-- 1 cfati cfati  112066 Oct  9 08:43 pycparser-2.19-py2.py3-none-any.whl
-rw-rw-r-- 1 cfati cfati   12099 Oct  9 08:43 six-1.12.0-py2.py3-none-any.whl
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q058228435/build]> for f in $(ls *.whl); do unzip ${f} > /dev/null; done
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q058228435/build]> ls
asn1crypto                         cffi-1.12.3-cp35-cp35m-linux_x86_64.whl        cryptography-2.7-cp35-cp35m-linux_x86_64.whl  pycparser-2.19-py2.py3-none-any.whl
asn1crypto-1.0.1.dist-info         cffi-1.12.3.dist-info                          cryptography-2.7.dist-info                    six-1.12.0.dist-info
asn1crypto-1.0.1-py3-none-any.whl  _cffi_backend.cpython-35m-x86_64-linux-gnu.so  pycparser                                     six-1.12.0-py2.py3-none-any.whl
cffi                               cryptography                                   pycparser-2.19.dist-info                      six.py
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q058228435/build]> PYTHONPATH=.:${PYTHONPATH} python3 ../code00.py
Python 3.5.2 (default, Jul 10 2019, 11:58:48) [GCC 5.4.0 20160609] 64bit on linux

OpenSSL version: OpenSSL 1.0.2t-fips  10 Sep 2019
FIPS_mode(): 0
FIPS_mode_set(1): 1
FIPS_mode(): 1
Success !!!

Done.

Похожие (более или менее) сообщения:

...