Skip to content

load provider keys from handle #934

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions ext/openssl/ossl_pkey.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
# include <openssl/engine.h>
#endif

#include <openssl/store.h>

/*
* Classes
*/
Expand Down Expand Up @@ -242,6 +244,49 @@ ossl_pkey_new_from_data(int argc, VALUE *argv, VALUE self)
return ossl_pkey_wrap(pkey);
}

#if OSSL_OPENSSL_PREREQ(3, 0, 0)
/*
* call-seq:
* OpenSSL::PKey.load(uri [, pwd ]) -> PKey
*
* Loads a private or public key from a URI.
* It can be a file://, or a provider specific handle.
*
* === Parameters
* * _uri_ is a file:// or provider specific thing, like a TPM2 handle:
* * _pwd_ is an optional password in case the thing is an encrypted
* PEM resource.
*/
static VALUE
ossl_pkey_load_from_handle(int argc, VALUE *argv, VALUE self)
{
EVP_PKEY *pkey;
VALUE handle, pass;
OSSL_STORE_CTX *sctx;

rb_scan_args(argc, argv, "11", &handle, &pass);
StringValue(handle);

const char *uri = RSTRING_PTR(handle);
sctx = OSSL_STORE_open(uri, NULL /* ui_method */, NULL /* ui_data */,
NULL /* post_process */,
NULL /* post_process_data */);

if(sctx == NULL)
ossl_raise(ePKeyError, "Could not initialize load ctx");

OSSL_STORE_INFO *store1 = OSSL_STORE_load(sctx);
if(store1 == NULL)
ossl_raise(ePKeyError, "Could not load key");

pkey = OSSL_STORE_INFO_get1_PKEY(store1);
if(pkey == NULL)
ossl_raise(ePKeyError, "Could not decode as keyh");

return ossl_pkey_wrap(pkey);
}
#endif

static VALUE
pkey_ctx_apply_options_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, ctx_v))
{
Expand Down Expand Up @@ -1733,6 +1778,10 @@ Init_ossl_pkey(void)
cPKey = rb_define_class_under(mPKey, "PKey", rb_cObject);

rb_define_module_function(mPKey, "read", ossl_pkey_new_from_data, -1);
#if OSSL_OPENSSL_PREREQ(3, 0, 0)
rb_define_module_function(mPKey, "load_from_handle", ossl_pkey_load_from_handle, -1);
#endif

rb_define_module_function(mPKey, "generate_parameters", ossl_pkey_s_generate_parameters, -1);
rb_define_module_function(mPKey, "generate_key", ossl_pkey_s_generate_key, -1);
rb_define_module_function(mPKey, "new_raw_private_key", ossl_pkey_new_raw_private_key, 2);
Expand Down
34 changes: 34 additions & 0 deletions sample/provider.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
require 'openssl'
require 'pathname'
require 'fileutils'

# note that this assumes that commands like:
# tpm2_createak --tcti=swtpm:port=4523 -C 0x81010001 -G rsa -g sha256 -s rsassa -c ak_rsa.ctxi -u ak_rsa.pub -n ak_rsa.name
# tpm2_evictcontrol --tcti=swtpm:port=4523 -C o -c ak_rsa.ctx 0x81010003
# have been run

cwd=Pathname.new(FileUtils.pwd())

tpmstatedir = cwd + "tpmstate"
FileUtils.mkdir_p(tpmstatedir)
ENV['TPM2OPENSSL_TCTI']="swtpm:port=4523"
if !File.exist?(tpmstatedir + "tpm2-00.permall")
system("swtpm_setup --tpm-state #{tpmstatedir} --tpm2 --createek")
end

# startup-clear implies not-need-init, and otherwise swtpm returns error 0x101.
# and the provider won't even load.
#system("swtpm socket --daemon --server type=tcp,port=4523 --ctrl type=tcp,port=4524 --tpmstate dir=#{tpmstatedir} --tpm2 --log file=/var/tmp/tpm2.log --flags startup-clear")
sleep(1)
prov01=OpenSSL::Provider.load("tpm2")
print "Loaded #{OpenSSL::VERSION}\n"
#print OpenSSL::PKey.methods.sort; print "\n"
#ENV['TSS2_LOG']="all+ERROR,marshal+TRACE,tcti+DEBUG"
pkey = OpenSSL::PKey.load_from_handle("handle:0x81010003")
#pkey=prov01.pkey
print pkey
print pkey.inspect
print "Done\n"



Loading