I think the password attribute is mandatory in the map describing the private key.
When I tried to use the :crypto engine API with a YubiKey in the past I got stuck on the OpenSC PKCS#11 driver asking for a PIN using stdin/stdout. The BEAM has its own I/O handling and doesn’t let me enter the PIN. It seems weird to have a library try and perform interactive I/O like that, and I guess it must be possible to pass the PIN through the API instead, but I haven’t found a way.
I hate to jump on an old post but I kept running into this post when trying to solve how to perform digital signatures with a YubiKey. I was not able to solve how to perform the signature using a certificate in slot 9c (cert #02) because it requires user input for every signature event but slot 9e (cert #04) allowed me to login using pin once and perform a signature.
Here is the related code for posterity’s sake:
def digital_signature(string, %{pin: _pin, slot: _slot} = opts) do
{:ok, engine} = load_engine()
privKey = private_key(engine, opts)
signature = :crypto.sign(:ecdsa, :sha256, string, privKey)
end
def load_engine() do
:crypto.engine_load(
"dynamic",
[{"SO_PATH", libpkcs}, {"ID", "pkcs11"}, {"LOAD", ""}],
[{"MODULE_PATH", "/usr/lib/libykcs11.so"}]
)
end
def private_key(engine, %{pin: pin, slot: slot}) do
%{
engine: engine,
key_id:
"pkcs11:object=X.509%20Certificate%20for%20Digital%20Signature;pin-value=#{pin};id=%#{
slot
}"
}
end