2011-05-04 2 views

Répondre

3

Le mappage des structures C à partir des fichiers d'en-tête (openssl/evp.h et _hashopenssl.c dans votre cas) est simple, mais n'est pas toujours portable sur différentes versions. Ici, il est pour mon environnement:

from ctypes import * 

PyObject_HEAD = [ 
    ('ob_refcnt', c_size_t), 
    ('ob_type', c_void_p), 
] 

class EVP_MD(Structure): 
    _fields_ = [ 
     ('type', c_int), 
     ('pkey_type', c_int), 
     ('md_size', c_int), 
     ('flags', c_ulong), 
     ('init', c_void_p), 
     ('update', c_void_p), 
     ('final', c_void_p), 
     ('copy', c_void_p), 
     ('cleanup', c_void_p), 
     ('sign', c_void_p), 
     ('verify', c_void_p), 
     ('required_pkey_type', c_int*5), 
     ('block_size', c_int), 
     ('ctx_size', c_int), 
    ] 

class EVP_MD_CTX(Structure): 
    _fields_ = [ 
     ('digest', POINTER(EVP_MD)), 
     ('engine', c_void_p), 
     ('flags', c_ulong), 
     ('md_data', POINTER(c_char)), 
    ] 

class EVPobject(Structure): 
    _fields_ = PyObject_HEAD + [ 
     ('name', py_object), 
     ('ctx', EVP_MD_CTX), 
    ] 

Voici un exemple sur la façon de l'utiliser pour save and restore state of hash object:

import hashlib 

hash = hashlib.md5('test') 
print hash.hexdigest() 

c_evp_obj = cast(c_void_p(id(hash)), POINTER(EVPobject)).contents 
ctx = c_evp_obj.ctx 
digest = ctx.digest.contents 
state = ctx.md_data[:digest.ctx_size] 

hash2 = hashlib.md5() 
c_evp_obj = cast(c_void_p(id(hash2)), POINTER(EVPobject)).contents 
ctx = c_evp_obj.ctx 
digest = ctx.digest.contents 
memmove(ctx.md_data, state, digest.ctx_size) 
print hash2.hexdigest() 
+0

Exactement ce que je avais besoin. Merci beaucoup :) – est

+1

@est, attention: vous devrez suivre le code openssl, si vous restez avec cette solution: si EVP_MD/EVP_MD_CTX change dans le code openssl, votre code python va casser. Par exemple, le code ci-dessus ne fonctionnera pas avec toutes les versions d'openssl antérieures à openssl-0.9.7. – abbot

+0

Merci d'avoir posté ce message. Pour le point de @ abbot, ce code nécessite une mise à jour sur Python 3.5+ et 2.7.13+ ('('ctx', EVP_MD_CTX)' devient '('ctx', POINTER (EVP_MD_CTX))'). J'ai fini par emballer une bibliothèque basée sur ceci et d'autres recettes: https://github.com/kislyuk/rehash – weaver

Questions connexes