Python调用OpenSSL函数段错误

时间:2017-02-12 23:39:46

标签: python-3.x openssl

我从Apple的iOS开发人员门户网站下载了针对PushNotifications的.p8文件。

我正在尝试使用Python中的以下代码加载P8文件:

from ctypes import *
OpenSSL = cdll.LoadLibrary("/opt/local/lib/libssl.1.0.0.dylib")


def loadPrivateKey(path):
    bio = OpenSSL.BIO_new_file(path.encode("utf-8"), "rb".encode("utf-8"))
    #pKey = OpenSSL.PEM_read_bio_PrivateKey(bio, None, None, None)
    OpenSSL.BIO_free(bio)

def main():
    loadPrivateKey("/users/Brandon/Desktop/APNsAuthKey.p8")

main()

然而,它在行上划分了错误:OpenSSL.BIO_free(bio)。我已经检查过bio是否具有0以外的值(确实如此)。

如果我在C中做同样的事情,它会起作用:

struct EVP_PKEY* loadPrivateKey(const char* path)
{
    struct BIO* bio = BIO_new_file(path, "rb");
    struct EVP_PKEY* pKey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
    BIO_free(bio);
    return pKey;
}

int main()
{
    struct EVP_PKEY* pKey = loadPrivateKey("/users/Brandon/Desktop/APNsAuthKey.p8");
    EVP_PKEY_free(pKey);
}

我已在C中验证代码是否有效,并且我已使用它来签署数据。我无法在Python3中执行相同的操作,因为使用代码11释放BIO段错误。

我尝试了pyOpenssl,当我尝试使用loadprivatekey(FILETYPE_PEM, key)读取密钥时,它也会出现段错误,其中key是P8文件的内容。

为什么会出现段错误?

1 个答案:

答案 0 :(得分:2)

如果其他人遇到同样的问题,你必须指定argtypesrestype。为此,您需要将函数指针指定给临时变量,指定类型,然后使用临时变量调用它。

示例:

from ctypes import *
OpenSSL = cdll.LoadLibrary("/opt/local/lib/libssl.1.0.0.dylib")


def BIO_new_file(path):
    BIO_new_file_func = OpenSSL.BIO_new_file
    BIO_new_file_func.argtypes = [c_char_p, c_char_p]
    BIO_new_file_func.restype = c_void_p
    return BIO_new_file_func(path.encode("utf-8"), "rb".encode("utf-8"))

def BIO_free(bio):
    BIO_free_func = OpenSSL.BIO_free
    BIO_free_func.argtypes = [c_void_p]
    BIO_free_func.restype = None
    return BIO_free_func(bio)


def loadPrivateKey(path):
    bio = BIO_new_file(path)
    #pKey = PEM_read_bio_PrivateKey(bio, None, None, None)
    BIO_free(bio)
    #return pKey

def main():
    loadPrivateKey("/users/Brandon/Desktop/APNsAuthKey.p8")

main()

我的印象是,我只需要用正确的参数调用函数,它就可以工作,但我错了。你必须指定类型!否则请使用FFI,让您的生活更轻松。