Python: 3.9.16OpenSSL: 3.0.8
fips_ccode.c
#include <stdio.h>
#include <stdlib.h>
#include <openssl/provider.h>
#include "openssl/md5.h"
int main(void)
{
OSSL_PROVIDER* fips;
OSSL_PROVIDER* base;
const char* default_search_path = "/tmp/fips_files/";
OSSL_PROVIDER_set_default_search_path(NULL, default_search_path);
int load_config = OSSL_LIB_CTX_load_config(NULL, "/tmp/fips_files/openssl.cnf") ;
printf("loading config:%dn", load_config);
fips = OSSL_PROVIDER_load(NULL, "fips");
printf("value:%xn",fips);
printf("Success to load FIPS providern");
base = OSSL_PROVIDER_load(NULL, "base");
printf("Success to load base providern");
}
fips_python.py
import ctypes
import os
import ssl
import ssl, os
import hashlib
BASEDIR="/tmp/"
FILENAME="libcrypto.so.3"
def get_crypto_lib_path():
return os.path.join(BASEDIR, FILENAME)
crypto_context = ctypes.CDLL(os.path.join(BASEDIR, get_crypto_lib_path()))
crypto_context.OSSL_PROVIDER_set_default_search_path.argtypes = [ctypes.c_char_p, ctypes.c_wchar_p]
crypto_context.OSSL_PROVIDER_set_default_search_path.restype = ctypes.c_char
crypto_context.OSSL_PROVIDER_set_default_search_path(None, "/tmp/fips_files/")
crypto_context.OSSL_LIB_CTX_load_config.argtypes = [ctypes.c_char_p, ctypes.c_wchar_p]
crypto_context.OSSL_LIB_CTX_load_config.restype = ctypes.c_int
load_config = crypto_context.OSSL_LIB_CTX_load_config(None, "/tmp/fips_files/openssl.cnf")
print("load config:", load_config)
crypto_context.OSSL_PROVIDER_load.argtypes = [ctypes.c_char_p, ctypes.c_wchar_p]
crypto_context.OSSL_PROVIDER_load.restype = ctypes.c_wchar_p
base_load = crypto_context.OSSL_PROVIDER_load(None, "base")
print("base load ret value:", base_load)
crypto_context.OSSL_PROVIDER_load.argtypes = [ctypes.c_char_p, ctypes.c_wchar_p]
crypto_context.OSSL_PROVIDER_load.restype = ctypes.c_wchar_p
fips_load = crypto_context.OSSL_PROVIDER_load(None, "fips")
print("fips load ret value:", fips_load)
在这里我看到加载提供程序"提示"one_answers";base"使用"OSSL_PROVIDER_load"在python中使用ctypes函数。在这里加载c函数的正确方法是什么?使用的参数类型是否正确?
清单[Python。ctypes - Python的外部函数库。
代码中有一堆错误:
-
LibCrypto的路径计算不正确(BASEDIR被附加两次)
-
你想使用OpenSSL v3.0的功能,但LibCrypto的名字暗示v1.1。这两者之间有很大的区别。
显然(除非libcrypto.so.1.1是一个容易引起误解的名称SymLink),这些函数将不存在,因此无法加载 -
Python函数原型与C函数原型不同,可在以下地址找到:
-
[OpenSSL]: OSSL_LIB_CTX_load_config
-
[OpenSSL]: OSSL_PROVIDER_set_default_search_path
生成U定义havior。查看[SO]:通过ctypes从Python调用的C函数返回不正确的值(@CristiFati的答案)了解更多详细信息
-
-
还有其他(比如不检查函数返回码),但与之前的相比,这些只是轻量级的
我准备了一个小例子来修复3和点。
code00.py:
#!/usr/bin/env python
import ctypes as cts
import os
import sys
PATH_LIBCRYPTO = "../q069539286/docker/openssl-1.1.1g/lib/libcrypto.so.1.1.1g"
PATH_LIBCRYPTO = "/tmp/libcrypto.so.1.1"
PATH_CFG = b"/tmp/fips_files/"
# @TODO - cfati: Use my paths
PATH_OSSL3_BASE = "/usr/local/pc064/openssl/openssl/3.0.10"
PATH_LIBCRYPTO = os.path.join(PATH_OSSL3_BASE, "lib", "libcrypto.so.3")
PATH_CFG = os.path.join(PATH_OSSL3_BASE.encode(), b"ssl")
POSSL_LIB_CTX = cts.c_void_p
POSSL_PROVIDER = cts.c_void_p
def main(*argv):
libcrypto = cts.CDLL(PATH_LIBCRYPTO)
OSSL_PROVIDER_set_default_search_path = libcrypto.OSSL_PROVIDER_set_default_search_path
OSSL_PROVIDER_set_default_search_path.argtypes = (POSSL_LIB_CTX, cts.c_char_p)
OSSL_PROVIDER_set_default_search_path.restype = cts.c_int
OSSL_LIB_CTX_load_config = libcrypto.OSSL_LIB_CTX_load_config
OSSL_LIB_CTX_load_config.argtypes = (POSSL_LIB_CTX, cts.c_char_p)
OSSL_LIB_CTX_load_config.restype = cts.c_int
OSSL_PROVIDER_load = libcrypto.OSSL_PROVIDER_load
OSSL_PROVIDER_load.argtypes = (POSSL_LIB_CTX, cts.c_char_p)
OSSL_PROVIDER_load.restype = POSSL_PROVIDER
res = OSSL_PROVIDER_set_default_search_path(None, PATH_CFG)
if res == 0:
print("OSSL_PROVIDER_set_default_search_path error")
return 1
res = OSSL_LIB_CTX_load_config(None, os.path.join(PATH_CFG, b"openssl.cnf"))
if res == 0:
print("OSSL_LIB_CTX_load_config error")
return 1
base_provider = OSSL_PROVIDER_load(None, b"base")
fips_provider = OSSL_PROVIDER_load(None, b"fips")
print(f"Base: {base_provider}nFIPS: {fips_provider}")
if __name__ == "__main__":
print("Python {:s} {:03d}bit on {:s}n".format(" ".join(elem.strip() for elem in sys.version.split("n")),
64 if sys.maxsize > 0x100000000 else 32, sys.platform))
rc = main(*sys.argv[1:])
print("nDone.n")
sys.exit(rc)
:
[cfati@cfati-5510-0:/mnt/e/Work/Dev/StackExchange/StackOverflow/q075889485]> python ./code00.py Python 3.8.18 (default, Aug 25 2023, 13:20:30) [GCC 11.4.0] 064bit on linux Base: 17667472 FIPS: None Done.
指出:
以上输出:
工作,但FIPS未在默认配置
中启用Used [GitHub]: CristiFati/prebuild - binaries - (master) prebuild - binaries/OpenSSL
虽然CTypes是Python和C之间的一个很好的桥梁(我个人喜欢它),但它需要编写大量的样板代码。对于您的情况,可能有更好的替代方案,可以实现所需的功能。您可以研究一些OpenSSL包装Python,如:
[PyPI]: pyOpenSSL
[PyPI]:密码学
可能还要检查一下:
[SO]:如何在RHEL上使用SSL编译python3 ?SSL无法导入(@CristiFati的答案)
[SO]:如何在Visual Studio中包含OpenSSL (@CristiFati的答案)
您的后续问题:[SO]: OpenSSL 3.0.8: FIPS功能在自定义路径中不与libcrypto库一起工作(@CristiFati的答案):)