2010-02-03 2 views
2

J'utilise M2Crypto-0.20.2. Je veux utiliser engine_pkcs11 du projet OpenSC et le client PKI d'Aladdin pour l'authentification basée sur les jetons, ce qui rend les appels xmlrpc via ssl.Besoin d'aide en utilisant M2Crypto.Engine pour accéder à USB Token

from M2Crypto import Engine 

Engine.load_dynamic() 
dynamic = Engine.Engine('dynamic') 
# Load the engine_pkcs from the OpenSC project 
dynamic.ctrl_cmd_string("SO_PATH", "/usr/local/ssl/lib/engines/engine_pkcs11.so") 
Engine.cleanup() 

Engine.load_dynamic() 
# Load the Aladdin PKI Client 
aladdin = Engine.Engine('dynamic') 
aladdin.ctrl_cmd_string("SO_PATH", "/usr/lib/libeTPkcs11.so") 

key = aladdin.load_private_key("PIN","password") 

C'est l'erreur que je reçois:

key = pkcs.load_private_key("PIN","eT0ken") 
File "/usr/local/lib/python2.4/site-packages/M2Crypto/Engine.py", line 70, in load_private_key 
    return self._engine_load_key(m2.engine_load_private_key, name, pin) 
File "/usr/local/lib/python2.4/site-packages/M2Crypto/Engine.py", line 60, in _engine_load_key 
    raise EngineError(Err.get_error()) 
M2Crypto.Engine.EngineError: 23730:error:26096075:engine routines:ENGINE_load_private_key:not initialised:eng_pkey.c:112: 

Pour load_private_key(), ce qui devrait être adopté comme premier argument? La documentation M2Crypto ne l'explique pas.

Je ne reçois aucune erreur lors du chargement des moteurs, mais je ne suis pas sûr de les charger correctement. Il semble que l'identifiant du moteur doive être un nom spécifique mais je ne trouve cette liste nulle part. 'dynamic' travaille pour moi.

Toute aide serait appréciée!

Répondre

2

!!!! Trouvé

Oui, exactement la façon dont je viens. Par conséquent, ENGINE_init() n'est pas implémenté dans M2Crypto.Engine. Donc, une seule solution: patcher !!! (Très petite ...) donc j'ai créé une nouvelle méthode de moteur (en Engine.py)

def engine_initz(self): 
     """Return engine name""" 
     return m2.engine_initz(self._ptr) 

Pourquoi engine_initz?parce que engine_init est définit déjà SWIG/_engine.i ,:

void engine_init(PyObject *engine_err) { 
    Py_INCREF(engine_err); 
    _engine_err = engine_err; 
} 

Je ne sais pas vraiment ce qui est fait, donc j'ai préférais créer un nouveau ... Je viens d'ajouter les éléments suivants à SWIG/_engine.i:

%rename(engine_initz) ENGINE_init; 
extern int ENGINE_init(ENGINE *); 

et recompiler le __m2crypto.so, maintenant il suffit d'ajouter un "pkcs11.engine_initz()" avant de lancer la clé privée, et cela fonctionne .....

+0

Bon travail! J'ai suivi vos instructions pour patcher M2Crypto et j'ai pu aussi passer l'erreur d'initialisation. Je vous remercie. – Becky

+0

Bon travail! Pourriez-vous déposer un bug sur M2Crypto? De plus, pourriez-vous indiquer à quel moment 'ENGINE_init()' doit-il être appelé? –

+0

J'ai changé l'actuel m2.engine_init en engine_init_error, exposé m2.engine_init et engine_finish et ajouté les méthodes init et finish à la classe Engine. Vérifié dans le tronc M2Crypto, s'il vous plaît tester avant de faire la prochaine version. –

0

En regardant le pastebin link Becky a fourni, je crois qu'il se traduit par quelque chose comme ça dans la nouvelle API:

from M2Crypto import Engine, m2 

dynamic = Engine.load_dynamic_engine("pkcs11", "/Users/martin/prefix/lib/engines/engine_pkcs11.so") 

pkcs11 = Engine.Engine("pkcs11") 

pkcs11.ctrl_cmd_string("MODULE_PATH", "/Library/OpenSC/lib/opensc-pkcs11.so") 

r = pkcs11.ctrl_cmd_string("PIN", sys.argv[1]) 

key = pkcs11.load_private_key("id_01") 

Je fais le pari que si vous remplacez «/Users/martin/préfixe/lib/moteurs /engine_pkcs11.so "avec" /usr/local/ssl/lib/engines/engine_pkcs11.so "et" /Library/OpenSC/lib/opensc-pkcs11.so "avec" /usr/lib/libeTPkcs11.so "vous pourriez Faites-le travailler avec Aladdin.

0

C'est exactement le code que j'ai essayé. Mais il a pris fin avec l'erreur suivante:

Traceback (most recent call last): 
    File "prog9.py", line 13, in <module> 
    key = pkcs11.load_private_key("id_45") 
    File "/usr/lib/pymodules/python2.5/M2Crypto/Engine.py", line 70, in load_private_key 
    return self._engine_load_key(m2.engine_load_private_key, name, pin) 
    File "/usr/lib/pymodules/python2.5/M2Crypto/Engine.py", line 60, in _engine_load_key 
    raise EngineError(Err.get_error()) 
M2Crypto.Engine.EngineError: 11814:error:26096075:engine outines:ENGINE_load_private_key:not initialised:eng_pkey.c:112: 

J'utilise OpenSC PKCS11 lib, pas aladdin lib. Mais je ne pense pas que le problème soit clos.

0

J'ai essayé le code que Heikki a suggéré (moins une ligne) et j'ai eu la même erreur que Erlo. Pour load_private_key(), comment savoir ce qu'il faut mettre en argument?

dynamic = Engine.load_dynamic_engine("pkcs11", "/usr/local/ssl/lib/engines/engine_pkcs11.so") 
# m2.engine_free(dynamic) this line gave me an error TypeError: in method 'engine_free', argument 1 of type 'ENGINE *' 

pkcs11 = Engine.Engine("pkcs11") 
pkcs11.ctrl_cmd_string("MODULE_PATH", "/usr/lib/libeTPkcs11.so") 

r = pkcs11.ctrl_cmd_string("PIN", "password") 

key = pkcs11.load_private_key("id_01") 
0

Je pense que le problème n'est pas vraiment le "load_private_key()". C'est comme si quelque chose manquait entre la définition "MODULE_PATH" et l'appel load_private_key(). Que se passe-t-il si vous remplacez "/usr/lib/libeTPkcs11.so" par un mauvais chemin? Dans mon cas, je n'ai aucune erreur liée à ceci.

J'ai couru « pcscd » au premier plan avec un haut niveau de débogage, il n'y a pas d'appel à la carte à puce pendant l'exécution de python ... Donc definitly, je ne comprends pas ce qui ne va pas ...

L'équivalent dans "openssl" utilise la commande "-pre". Les "-pre" (par opposition au "-post") sont des commandes envoyées au moteur avant le chargement. Peut-être que nous devons appeler une méthode qui "charger" le moteur après tous les appels "ctrl_cmd_string" ?? ...

Perdu: -/

+0

Je m perdue aussi :) Ahh, oui si je mets dans un mauvais chemin je reçois toujours la même erreur "non initialisée". Savez-vous quand utiliser load_dynamic_engine() par rapport à load_dynamic()? L'ancien exemple de code auquel j'ai posté un lien a un m2.engine_init() après le ctrl_cmd_strings(). Je n'ai encore rien trouvé d'équivalent à cela. Je vous tiendrai au courant si j'apprends quelque chose. – Becky

+0

Je pense qu'avant l'envoi de la broche, le moteur doit être initialisé et ce n'est pas le cas. La documentation du moteur openssl parle de références structurelles et fonctionnelles. Pour utiliser une fonctionnalité de moteur, vous avez besoin d'une référence fonctionnelle obtenue en appelant la fonction ENGINE_init(). Je ne sais pas comment cela se traduit par le monde python/m2crypto. – Becky

+0

Jetez un coup d'œil aux fichiers Engine.py et _engine.i. m2.engine_init() configure simplement la classe d'exception EngineError. Cela se produit automatiquement lorsque vous importez le moteur dans la nouvelle API. –

1

Je ne sais pas quoi et pourquoi le code engine_init présent dans le M2Crypto actuel est supposé faire. L'exposition ENGINE_init() comme engine_init2 avec le correctif suivant pour M2Crypto aide:

Index: SWIG/_engine.i 
=================================================================== 
--- SWIG/_engine.i (revision 719) 
+++ SWIG/_engine.i (working copy) 
@@ -44,6 +44,9 @@ 
%rename(engine_free) ENGINE_free; 
extern int ENGINE_free(ENGINE *); 

+%rename(engine_init2) ENGINE_init; 
+extern int ENGINE_init(ENGINE *); 
+ 
/* 
    * Engine id/name functions 
    */ 

Après cela, le code suivant me prend plus (mais urllib ne fonctionne pas complètement pour moi actuellement):

import sys, os, time, cgi, urllib, urlparse 
from M2Crypto import m2urllib2 as urllib2 
from M2Crypto import m2, SSL, Engine 

# load dynamic engine 
e = Engine.load_dynamic_engine("pkcs11", "/Users/martin/prefix/lib/engines/engine_pkcs11.so") 
pk = Engine.Engine("pkcs11") 
pk.ctrl_cmd_string("MODULE_PATH", "/Library/OpenSC/lib/opensc-pkcs11.so") 

m2.engine_init2(m2.engine_by_id("pkcs11")) # This makes the trick 

cert = e.load_certificate("slot_01-id_01") 
key = e.load_private_key("slot_01-id_01", sys.argv[1]) 

ctx = SSL.Context("sslv23") 
ctx.set_cipher_list("HIGH:!aNULL:!eNULL:@STRENGTH") 
ctx.set_session_id_ctx("foobar") 
m2.ssl_ctx_use_x509(ctx.ctx, cert.x509) 
m2.ssl_ctx_use_pkey_privkey(ctx.ctx, key.pkey) 

opener = urllib2.build_opener(ctx) 
urllib2.install_opener(opener) 
Questions connexes