Нужна помощь с использованием M2Crypto.Engine для доступа к USB-токену - PullRequest
2 голосов
/ 03 февраля 2010

Я использую M2Crypto-0.20.2. Я хочу использовать engine_pkcs11 из проекта OpenSC и клиента PKI Aladdin для аутентификации на основе токенов, делая вызовы xmlrpc через ssl.

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

Это ошибка, которую я получаю:

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:

Для load_private_key(), что должно быть передано в качестве первого аргумента? Документация M2Crypto не объясняет этого.

Я не получаю никаких ошибок при загрузке двигателей, но я не уверен, правильно ли я их загружаю. Кажется, что идентификатор двигателя должен быть конкретным именем, но я нигде не нахожу этот список. 'dynamic' работает на меня.

Любая помощь будет оценена!

Ответы [ 6 ]

2 голосов
/ 04 февраля 2010

Найдено !!!!

Да, именно так, откуда я пришел.

Итак, фактически ENGINE_init () не реализован в M2Crypto.Engine.Итак, решение только одно: исправление ошибок !!!(очень маленький ...), поэтому я создал новый метод Engine (в Engine.py)

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

Почему engine_initz?потому что engine_init уже определен в SWIG / _engine.i,:

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

Я действительно не знаю, что сделано, поэтому я предпочел создать новый ... Итак, я только что добавилследующее в SWIG / _engine.i:

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

И перекомпилируйте __m2crypto.so, теперь просто добавьте pkcs11.engine_initz () перед запуском закрытого ключа, и это работает .....

1 голос
/ 05 февраля 2010

Я не знаю, что и почему должен делать код engine_init, присутствующий в текущем M2Crypto. Помогает ENGINE_init () как engine_init2 со следующим патчем для M2Crypto:

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
  */

После этого следующий код ведет меня дальше (но в настоящее время urllib не работает для меня полностью):

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)
0 голосов
/ 04 февраля 2010

Я думаю, что проблема не в «load_private_key ()». Как будто чего-то не хватает между определением «MODULE_PATH» и вызовом load_private_key (). Что произойдет, если вы замените «/usr/lib/libeTPkcs11.so» неверным путем? В моем случае у меня нет ошибок, связанных с этим.

Я запустил "pcscd" на переднем плане с высоким уровнем отладки, во время выполнения python нет вызова смарт-карты ... Так что я точно не понимаю, в чем дело ...

Эквивалентом в "openssl" является использование команды "-pre". «-Pre» (напротив «-post») - команда, отправляемая в двигатель перед загрузкой. Возможно, нам нужно вызвать метод, который «загружает» движок после всех вызовов «ctrl_cmd_string» ?? ...

Потерян: - /

0 голосов
/ 04 февраля 2010

Я попробовал код, который предложил Хейкки (минус одна строка), и получил ту же ошибку, что и Эрло. Для load_private_key (), как я знаю, что ввести в качестве аргумента?

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 голосов
/ 04 февраля 2010

Это именно тот код, который я пробовал. Но это закончилось следующей ошибкой:

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:

Я использую OpenSC PKCS11 lib, а не aladdin lib. Но я не думаю, что проблема закрыта.

0 голосов
/ 04 февраля 2010

Глядя на ссылку pastebin , предоставленную Бекки, я считаю, что в новом 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")

Так что я держу пари, что если вы замените "/ Users/martin/prefix/lib/engines/engine_pkcs11.so "с" /usr/local/ssl/lib/engines/engine_pkcs11.so "и" /Library/OpenSC/lib/opensc-pkcs11.so "с" / usr /lib / libeTPkcs11.so "вы можете заставить его работать с Aladdin.

...