latchset / pkcs11-provider

A pkcs#11 provider for OpenSSL 3.0+
Other
61 stars 39 forks source link

OSSL_STORE_load EC private key using pkcs11 URI #357

Closed vkarpenk closed 1 month ago

vkarpenk commented 6 months ago

Need help to debug access to EC private key in token using pkcs11 URI.

kuser@39895c7d96aa:/$ pkcs11-tool --module /usr/local/lib/libp11sgx.so.0.0.0 --token-label token_server --login --pin ..... --list-objects Private Key Object; EC label: client_key_priv ID: d2 Usage: decrypt, sign Access: sensitive Certificate Object; type = X.509 cert label: client_cert subject: DN: CN=nserver

info = OSSL_STORE_load(store) loop can only find the x509 cert type OSSL_STORE_INFO_CERT.

When the pkcs11-provider functions find the CKO_PRIVATE_KEY EC object, they fails to load with this error: " Error: 0x00000005; Not a public Key"

[session.c:307] session_new(): Total sessions: 2
[interface.gen.c:214] p11prov_OpenSession(): Calling C_OpenSession
[session.c:80] token_session_open(): C_OpenSession ret:0 (session: 28)
[interface.gen.c:253] p11prov_GetSessionInfo(): Calling C_GetSessionInfo
[objects.c:991] p11prov_obj_find(): Find objects [class=3, id-len=0, label=client_key_priv]
[interface.gen.c:445] p11prov_FindObjectsInit(): Calling C_FindObjectsInit
[interface.gen.c:467] p11prov_FindObjects(): Calling C_FindObjects
[interface.gen.c:487] p11prov_FindObjectsFinal(): Calling C_FindObjectsFinal
[objects.c:1075] p11prov_obj_find(): Find objects: found 0 objects; Returning 0
[session.c:861] p11prov_get_session(): Get session on slot 2, reqlogin=true, rw=false
[session.c:894] p11prov_get_session(): cycle through available slots
[session.c:590] check_slot(): Checking Slot id=2, uri=0x55c19c6a7500, mechtype=ffffffffffffffff, rw=false)
[store.c:126] store_fetch(): Failed to get session to load keys (slotid=2, ret=e0)
[store.c:333] p11prov_store_load(): found CKO_PRIVATE_KEY
[store.c:452] p11prov_store_export_object(): store (0x55c19c5d3860) export object 0x55c19c6a76f0, 120
[provider.c:586] p11prov_ctx_allow_export(): allow_export = 0
[objects.c:1980] p11prov_obj_export_public_key(): Error: 0x00000005; Not a public Key
[store.c:420] p11prov_store_eof(): store eof (0x55c19c5d3860)
[store.c:435] p11prov_store_close(): store close (0x55c19c5d3860)
[store.c:34] p11prov_store_ctx_free(): store ctx free (0x55c19c5d3860)
[objects.c:433] p11prov_obj_free(): Free Object: 0x55c19c6a76f0 (handle:27)

uri="pkcs11:token=token_client;object=client_key_priv;type=private;pin-value=...."

I also generated an EC key pair in the token, and it failed with the same error.

Jakuje commented 6 months ago

For ECDSA you need both public and private key on the token, because there is no way to derive the public attributes from the private key object. In theory, you could get the public key from the certificate, but in any case, it would have to have the same ID as the private key. Your listing does not show that.

Usage: decrypt, sign

Side note, private EC keys can not be used for decryption.

simo5 commented 6 months ago

@vkarpenk can you please provide what command line or what program you are using to cause this error ?

simo5 commented 6 months ago

(also please state if you re using latest main branch code, or some release version)

vkarpenk commented 5 months ago

The application I'm testing is netopeer2 client and server. I modified the libnetconf2 library to add private key handle to SSL context using pkcs11 URIs with the provider API.

      store = OSSL_STORE_open(uri, NULL, NULL, NULL, NULL);
        if (!store) {
            ERR(NULL, "fail: OSSL_STORE_open() [uri=%s] %s\n", uri, ERR_reason_error_string(ERR_get_error()));
            OSSL_STORE_close(store);
            goto cleanup;
        }

        OSSL_STORE_INFO *info = NULL;
        for (info = OSSL_STORE_load(store);
            info != NULL;
            info = OSSL_STORE_load(store)) {

            int ossl_type = OSSL_STORE_INFO_get_type(info);

            if (ossl_type == OSSL_STORE_INFO_PKEY) {
                pkey = OSSL_STORE_INFO_get1_PKEY(info);
                break;
            } 
        }

I generated an EC key pair with the same id in the token

Public Key Object; EC EC_POINT 256 bits EC_POINT: 04410403d77cbfb25275778f78e1d64fbb6728c7076fccda61af91a64563eb3f2051860c0b6b1c77 4385801dbdfcfb8526b550e49eab4594f9b923285b6d8b975b7882 EC_PARAMS: 06082a8648ce3d030107 label: my_key ID: 1111 Usage: encrypt, verify, wrap Access: local Private Key Object; EC label: my_key ID: 1111 Usage: decrypt, sign, unwrap Access: sensitive, always sensitive, never extractable, local

This fixed the previous error, but it does not find the private key to add it to the SSL context

[store.c:333] p11prov_store_load(): found CKO_PRIVATE_KEY
[store.c:452] p11prov_store_export_object(): store (0x557da0005860) export object 0x557da00e7050, 120
[provider.c:586] p11prov_ctx_allow_export(): allow_export = 0
[objects.c:1620] get_public_attrs(): Get Public Attributes (obj=0x557da00e7050, atrs=0x7fff9de9c0d0, num=1)
[objects.c:1620] get_public_attrs(): Get Public Attributes (obj=0x557da00e7050, atrs=0x7fff9de9c0d0, num=2)
[store.c:420] p11prov_store_eof(): store eof (0x557da0005860) [store.c:435] p11prov_store_close(): store close (0x557da0005860)
[store.c:34] p11prov_store_ctx_free(): store ctx free (0x557da0005860)
[objects.c:433] p11prov_obj_free(): Free Object: 0x557da00e7050 (handle:76)
nc ERROR: fail: OSSL_STORE_INFO_PKEY lookup [uri=pkcs11:token=token_client;object=my_key;pin-value=1234]

I'm using the latest main branch of pkcs11-provider.

Jakuje commented 5 months ago

nc ERROR: fail: OSSL_STORE_INFO_PKEY lookup [uri=pkcs11:token=token_client;object=my_key;pin-value=1234]

The PKCS#11 URI says the pin-value is a part of pk11-query so it should come after ? instead of the ;. But I see this used in the tests in pkcs11-provider everywhere so its likely something we should be more strict, but likely not an issue in your test.

https://www.rfc-editor.org/rfc/rfc7512.html#section-2.3

You also use token=token_client while initial description had token=token_server

There is likely something wrong with the key on pkcs11 layer. Can you get the pkcs11 calls trace, for example with pkcs11-spy or p11-kit log-calls: option (or any that is native to your pkcs11 module).

simo5 commented 4 months ago

@vkarpenk it would be useful if you could enable debug logging in pkcs11-provider like so: export PKCS11_PROVIDER_DEBUG=file:/tmp/debug.log,level:2

Then show the log, there may be an issue with the public attributes requested. We do have code to let openssl ask for public attribute on the private key, by doing some internal magic to find the associated public key, and that may be failing for some reason.

A debug log may give us enough clues to find why.

simo5 commented 1 month ago

No activity so closing, please open a new bug with the requested info if this is still an issue.