<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <div class="moz-cite-prefix">Hi,<br>
      <br>
      On 14/12/20 21:01, George wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:7a3428c6-04ab-672e-b738-67680f9fc036@gmail.com">
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
      <div class="moz-cite-prefix">Ok, so I am not actually going to
        populate EVP_PKEY with a private key in the callback function<font
          size="+1">:<br>
        </font><font size="+1" face="monospace">int
          (*client_cert_cb)(SSL *ssl, X509 **x509, <b>EVP_PKEY **pkey</b>)</font><font
          size="+1" face="monospace">?<br>
          <br>
        </font><font size="+1">Instead, I will call </font><br>
        <font size="+1" face="monospace">EVP_PKEY
          *ENGINE_load_private_key(ENGINE *e, const char *key_id,
          UI_METHOD *ui_method, void *callback_data);<br>
        </font>to get the <font face="monospace">EVP_PKEY</font>, which
        will be used by OpenSSL to access the Smart Card.<br>
        <br>
        Once I get  <font size="+1"><font face="monospace">the
            resulting </font></font><font size="+1" face="monospace">EVP_PKEY
          using </font><font size="+1" face="monospace">ENGINE_load_private_key(...),
          how do I assign it to pkey in the callback function?<br>
          If I had private key I would use something like<br>
        </font> EVP_PKEY_assign_RSA(..)<br>
        Since I don't actually have a private key, should I use
        something else?<br>
        <br>
      </div>
    </blockquote>
    like Michael pointed out, my  eap-tls code is just an example of how
    you could handle a pkcs11 device; it does not us a callback at all,
    but my code loads the client cert+key upfront and avoids having to
    use a client callback altogether.<br>
    <br>
    I guess you could also use a client callback for this (perhaps in
    combination with SSL_CTX_set_client_cert_engine()) . In that case
    you would get the (pseudo) key from the engine like this<br>
       EVP_PKEY *engine_key = <font size="+1" face="monospace">ENGINE_load_private_key(ENGINE
      *e, const char *key_id, UI_METHOD *ui_method, void
      *callback_data);<br>
      and then set<br>
        pkey = &engine_key;<br>
      and see if that works.<br>
      Note that the </font><font size="+1" face="monospace">ENGINE_load_private_key()
      function *does* return a EVP_PKEY struct but that does not mean
      the entire private key is contained in it; a private key consists
      of a modulus and a private part (exponent, prime1, prime2, exponent1,
      exponent2 etc). the </font><font size="+1" face="monospace">ENGINE_load_private_key()
      call will return a struct containing the modulus but not the rest.
      You then use the engine to do the actual encryption and decryption.<br>
      <br>
      HTH,<br>
      <br>
      JJK<br>
      <br>
    </font><font size="+1" face="monospace"><br>
    </font>
    <blockquote type="cite"
      cite="mid:7a3428c6-04ab-672e-b738-67680f9fc036@gmail.com">
      <div class="moz-cite-prefix"> <br>
        <br>
        Thanks,<br>
        George<br>
        <br>
        <br>
        On 2020-12-14 12:59 p.m., Michael Wojcik wrote:<br>
      </div>
      <blockquote type="cite"
cite="mid:BN8PR18MB269202BE32C14ACB482E015DF9C70@BN8PR18MB2692.namprd18.prod.outlook.com"><br>
        <pre class="moz-quote-pre" wrap="">You can't get the private key from the smartcard. Instead, you have to let the engine do the encryption. I don't know what ENGINE_load_private_key actually does - in my PKCS#11 work I didn't have to get into this - but I suspect it just puts a key identifier into pkey.

Then what ought to happen is that you pass that pkey to OpenSSL where you need an EVP_PKEY, and OpenSSL will call the engine's appropriate method for whatever it needs to do, and the engine will tell the smartcard "do this thing using the key with this identifier".

I suggest you refer to a example such as the PPP code that Jan cited to see how it does this sort of thing.

Or you can take the approach that Paul suggests in his reply of writing your own engine specifically for your hardware, if you don't need generic PKCS#11 support. Basically, PKCS#11 gives you support for more devices, and in principle should do some of the work for you; but as Paul suggests, the PKCS#11 API and its dependence on external drivers and libraries means it's not easy to work with. In some cases where you only need to support one type of device (or a family of devices that all use the same driver / library) it might well be easier to just write a simple engine that only supports the features you need. You can use the source for the existing engines in OpenSSL to get an idea of what that looks like.

A few years back I forked the OpenSSL CAPI engine to make some fixes and enhancements, and that was pretty straightforward.

So if you have a well-documented API for your particular smartcard, with handy functions like "do this to get an RSA signature of a blob of data with this key ID and these parameters", you may want to try Paul's route. Really depends on your requirements and what kind of support you already have for your device.

And all of this changes in 3.0 with the new "provider" architecture, so you'll get to take another crack at it soon.

--
Michael Wojcik
</pre>
      </blockquote>
      <br>
    </blockquote>
    <br>
  </body>
</html>