2017-02-12 8 views
2

Ich habe eine .p8-Datei-Download von Apples iOS-Entwickler-Portal für PushNotifications.Python Aufruf OpenSSL-Funktion segfaults

Ich versuche, die P8-Datei mit dem folgenden Code in Python zu laden:

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() 

es jedoch Störungen auf der Linie seg: OpenSSL.BIO_free(bio). Ich habe überprüft, ob Bio einen anderen Wert als 0 hat (tut es).

Wenn ich die gleiche Sache in C tun, es funktioniert:

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); 
} 

I in C überprüft haben, dass der Code funktioniert und ich habe es verwendet, um Daten zu unterzeichnen. Ich habe nicht in der Lage gewesen, das gleiche in Python3 zu tun, weil die BIO Befreiung mit Code Segfaults 11.

ich pyOpenssl versucht habe, und es Segfaults auch wenn ich versuche, den Schlüssel mit loadprivatekey(FILETYPE_PEM, key) zu lesen, in dem Schlüssel der Inhalt der P8-Datei .

Irgendwelche Ideen, warum es segfault wäre?

+0

Welche Version von OpenSSL liefern Sie und welche Version von OpenSSL erwartet Python? OpenSSL 1.0.2 und OpenSSL 1.1.0 sind * nicht * binärkompatibel. – jww

+0

@ jww; Ich habe es gelöst. Nach dem Versuch für Stunden .. Es stellt sich heraus, dass Sie die Typen angeben müssen und die Typen müssen eine perfekte Übereinstimmung sein. Sonst schlägt es fehl. Aus irgendeinem seltsamen Grund "pyOpenSSL" segfaults, obwohl es 'ffi' verwendet. Am Ende habe ich die Lösung verwendet, die ich gepostet habe, da keine der Third-Party-Bibliotheken atm arbeitet und ich keine andere Lösung finden kann. – Brandon

Antwort

2

Falls jemand anderes die gleichen Probleme hat .. Sie müssen die argtypes und restype angeben. Um dies zu tun, müssen Sie den Funktionszeiger einer temporären Variablen zuweisen, die Typen angeben und sie dann mit dem temporären aufrufen.

Beispiel:

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() 

Ich hatte den Eindruck, dass ich gerade hatte, um die Funktionen mit den richtigen Argumenten aufrufen und es würde funktionieren, aber ich war falsch. Sie müssen die Typen angeben! Ansonsten verwenden Sie FFI und machen Sie Ihr Leben leichter.