Need help using M2Crypto.Engine to access USB Token

前端 未结 6 682
自闭症患者
自闭症患者 2021-01-07 00:09

I am using M2Crypto-0.20.2. I want to use engine_pkcs11 from the OpenSC project and the Aladdin PKI client for token based authentication making xmlrpc calls over ssl.

相关标签:
6条回答
  • 2021-01-07 00:46

    I don't know what and why the engine_init code present in current M2Crypto is supposed to do. Exposing ENGINE_init() as engine_init2 with the following patch to M2Crypto helps:

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

    After this, the following code takes me further (but urllib does not fully work for me currently):

    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 讨论(0)
  • 2021-01-07 00:48

    Looking at the pastebin link Becky provided, I believe it translates to something like this in the new 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")
    

    So I am betting that if you substitute "/Users/martin/prefix/lib/engines/engine_pkcs11.so" with "/usr/local/ssl/lib/engines/engine_pkcs11.so" and "/Library/OpenSC/lib/opensc-pkcs11.so" with "/usr/lib/libeTPkcs11.so" you might get it to work with Aladdin.

    0 讨论(0)
  • 2021-01-07 00:56

    Found !!!!

    Yes, exactly the way where I came from.

    So, actually the ENGINE_init() is not implemented in M2Crypto.Engine. So, only one solution: patching!!! (very small...) so I've created a new Engine method (in Engine.py)

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

    Why engine_initz ? because engine_init is already define in SWIG/_engine.i,:

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

    I don't really know what is done, so I've prefered creating a new one... So I've just added the following to SWIG/_engine.i:

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

    And recompile the __m2crypto.so, now just add a "pkcs11.engine_initz()" before launching the private key, and it works.....

    0 讨论(0)
  • 2021-01-07 01:03

    I think the problem is not really the "load_private_key()". It's like something is missing between "MODULE_PATH" definition and the load_private_key() call. What happen if you remplace "/usr/lib/libeTPkcs11.so" by a wrong path ? In my case I have no error related to this.

    I've run "pcscd" in foreground with high debug level, there is no call to smartcard during the python execution... So definitly, I don't understand what's wrong...

    The equivalent in "openssl" is using "-pre" command. The "-pre" (by opposite to the "-post") are command sent to the engine before loading. Perhaps we need to call a methode which "load" the engine after all "ctrl_cmd_string" calls ?? ...

    Lost :-/

    0 讨论(0)
  • 2021-01-07 01:04

    I tried the code that Heikki suggested (minus one line) and got the same error as Erlo. For load_private_key(), how do I know what to put in for the 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 讨论(0)
  • 2021-01-07 01:05

    That is exactly the code I've tried. But It ended with the following error:

    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:
    

    I'm using OpenSC PKCS11 lib, not aladdin lib. But I don't think the problem is closed.

    0 讨论(0)
提交回复
热议问题