2017-02-12 72 views
2

我有一個從Apple的iOS開發人員門戶PushNotifications .p8文件下載。Python調用OpenSSL函數segfaults

我試圖加載P8文件可以用Python下面的代碼:

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("https://stackoverflow.com/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("https://stackoverflow.com/users/Brandon/Desktop/APNsAuthKey.p8"); 
    EVP_PKEY_free(pKey); 
} 

我用C代碼工作已經驗證了,我用它來簽名數據。我在Python3一直無法做同樣的,因爲釋放的BIO代碼爲11

我已經試過pyOpenssl出現segfaults,也出現segfaults當我嘗試用loadprivatekey(FILETYPE_PEM, key)讀取密鑰,其中關鍵是P8文件的內容。

任何想法爲什麼它會segfault?

+0

您提供了哪個版本的OpenSSL,以及Python預期哪種版本的OpenSSL? OpenSSL 1.0.2和OpenSSL 1.1.0 *不是二進制兼容的。 – jww

+0

@wwww;我解決了它。試了幾個小時..事實證明,你需要指定類型和類型必須完美匹配。否則失敗。由於某些奇怪的原因,即使使用'ffi',pyOpenSSL'段錯誤。我結束了使用我發佈的解決方案,因爲沒有任何第三方庫工作atm,我找不到任何其他解決方案。 – Brandon

回答

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("https://stackoverflow.com/users/Brandon/Desktop/APNsAuthKey.p8") 

main() 

我的印象是,我不得不調用的函數用正確的參數之下,它會工作,但我錯了。你必須指定類型!否則使用FFI,讓你的生活更輕鬆。