kenh / keychain-pkcs11

A shared library that implements a PKCS#11 interface to the Apple Security framework
98 stars 10 forks source link

Unable to use keychain-pkcs11 to list certificate stored into Keychain #12

Open jycr opened 2 years ago

jycr commented 2 years ago

I'm looking for a way to use the certificates stored in the MacOS Keychain (with the private key export option disabled) via a PKCS#11 API.

I tried using keychain-pkcs11 with Java PKCS#11 provider but it doesn't work.

Java error log:

Information for provider SunPKCS11-Keychain-PKCS11
Library info:
  cryptokiVersion: 2.40
  manufacturerID: U.S. Naval Research Lab         
  flags: 0
  libraryDescription: Keychain PKCS#11 Bridge Library 
  libraryVersion: 1.00
All slots: 0
Slots with tokens: (none)
Exception in thread "main" java.security.ProviderException: Initialization failed
    at jdk.crypto.cryptoki/sun.security.pkcs11.SunPKCS11.<init>(SunPKCS11.java:387)
    at jdk.crypto.cryptoki/sun.security.pkcs11.SunPKCS11$1.run(SunPKCS11.java:118)
    at jdk.crypto.cryptoki/sun.security.pkcs11.SunPKCS11$1.run(SunPKCS11.java:115)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:569)
    at jdk.crypto.cryptoki/sun.security.pkcs11.SunPKCS11.configure(SunPKCS11.java:115)
    at Pkcs11MutualAuthenticationTest.listCertificates(Pkcs11MutualAuthenticationTest.java:49)
    at Pkcs11MutualAuthenticationTest.main(Pkcs11MutualAuthenticationTest.java:30)
Caused by: java.security.ProviderException: slotListIndex is 0 but token only has 0 slots
    at jdk.crypto.cryptoki/sun.security.pkcs11.SunPKCS11.<init>(SunPKCS11.java:368)
    ... 6 more

Here MacOS event log:

➜  ~ log stream --predicate 'subsystem = "mil.navy.nrl.cmf.pkcs11"' --level debug
Filtering the log data using "subsystem == "mil.navy.nrl.cmf.pkcs11""
Timestamp                       Thread     Type        Activity             PID    TTL  
2022-09-14 20:55:47.615569+0200 0x25321    Debug       0x0                  14552  0    java: (keychain-pkcs11.dylib) [mil.navy.nrl.cmf.pkcs11:general] C_GetFunctionList called
2022-09-14 20:55:47.615842+0200 0x25321    Debug       0x0                  14552  0    java: (keychain-pkcs11.dylib) [mil.navy.nrl.cmf.pkcs11:general] C_GetFunctionList returning CKR_OK
2022-09-14 20:55:47.615995+0200 0x25321    Debug       0x0                  14552  0    java: (keychain-pkcs11.dylib) [mil.navy.nrl.cmf.pkcs11:general] C_Initialize called
2022-09-14 20:55:47.616034+0200 0x25321    Debug       0x0                  14552  0    java: (keychain-pkcs11.dylib) [mil.navy.nrl.cmf.pkcs11:general] OS_LOCKING_OK set, using pthread locking
2022-09-14 20:55:47.617304+0200 0x25321    Debug       0x0                  14552  0    java: (keychain-pkcs11.dylib) [mil.navy.nrl.cmf.pkcs11:general] Program "java" is NOT set to ask for PIN, will let Security ask for the PIN
2022-09-14 20:55:47.617434+0200 0x25321    Debug       0x0                  14552  0    java: (keychain-pkcs11.dylib) [mil.navy.nrl.cmf.pkcs11:general] Program "java" has the Keychain Certificate slot DISABLED
2022-09-14 20:55:47.625206+0200 0x25321    Debug       0x0                  14552  0    java: (keychain-pkcs11.dylib) [mil.navy.nrl.cmf.pkcs11:general] Looking for identities for token com.apple.setoken
2022-09-14 20:55:47.627565+0200 0x25321    Debug       0x0                  14552  0    java: (keychain-pkcs11.dylib) [mil.navy.nrl.cmf.pkcs11:general] No identities found
2022-09-14 20:55:47.627644+0200 0x25321    Debug       0x0                  14552  0    java: (keychain-pkcs11.dylib) [mil.navy.nrl.cmf.pkcs11:general] Looking for identities for token com.apple.setoken:aks
2022-09-14 20:55:47.628745+0200 0x25321    Debug       0x0                  14552  0    java: (keychain-pkcs11.dylib) [mil.navy.nrl.cmf.pkcs11:general] No identities found
2022-09-14 20:55:47.628858+0200 0x25321    Debug       0x0                  14552  0    java: (keychain-pkcs11.dylib) [mil.navy.nrl.cmf.pkcs11:general] C_Initalize returning CKR_OK
2022-09-14 20:55:47.629072+0200 0x25321    Debug       0x0                  14552  0    java: (keychain-pkcs11.dylib) [mil.navy.nrl.cmf.pkcs11:general] C_GetInfo called
2022-09-14 20:55:47.629113+0200 0x25321    Debug       0x0                  14552  0    java: (keychain-pkcs11.dylib) [mil.navy.nrl.cmf.pkcs11:general] C_GetInfo returning CKR_OK
2022-09-14 20:55:47.640315+0200 0x25321    Debug       0x0                  14552  0    java: (keychain-pkcs11.dylib) [mil.navy.nrl.cmf.pkcs11:general] C_GetSlotList called
2022-09-14 20:55:47.640372+0200 0x25321    Debug       0x0                  14552  0    java: (keychain-pkcs11.dylib) [mil.navy.nrl.cmf.pkcs11:general] tokens_present = false, slot_list = 0x60000255c680, slot_num = 125601792
2022-09-14 20:55:47.640407+0200 0x25321    Debug       0x0                  14552  0    java: (keychain-pkcs11.dylib) [mil.navy.nrl.cmf.pkcs11:general] C_GetSlotList returning CKR_OK
2022-09-14 20:55:47.640425+0200 0x25321    Debug       0x0                  14552  0    java: (keychain-pkcs11.dylib) [mil.navy.nrl.cmf.pkcs11:general] C_GetSlotList called
2022-09-14 20:55:47.640442+0200 0x25321    Debug       0x0                  14552  0    java: (keychain-pkcs11.dylib) [mil.navy.nrl.cmf.pkcs11:general] tokens_present = false, slot_list = 0x60000255c680, slot_num = 1
2022-09-14 20:55:47.640462+0200 0x25321    Debug       0x0                  14552  0    java: (keychain-pkcs11.dylib) [mil.navy.nrl.cmf.pkcs11:general] C_GetSlotList returning CKR_OK
2022-09-14 20:55:47.641374+0200 0x25321    Debug       0x0                  14552  0    java: (keychain-pkcs11.dylib) [mil.navy.nrl.cmf.pkcs11:general] C_GetSlotList called
2022-09-14 20:55:47.641443+0200 0x25321    Debug       0x0                  14552  0    java: (keychain-pkcs11.dylib) [mil.navy.nrl.cmf.pkcs11:general] tokens_present = true, slot_list = 0x60000255c680, slot_num = 125601792
2022-09-14 20:55:47.641525+0200 0x25321    Debug       0x0                  14552  0    java: (keychain-pkcs11.dylib) [mil.navy.nrl.cmf.pkcs11:general] C_GetSlotList returning CKR_OK
2022-09-14 20:55:47.641550+0200 0x25321    Debug       0x0                  14552  0    java: (keychain-pkcs11.dylib) [mil.navy.nrl.cmf.pkcs11:general] C_GetSlotList called
2022-09-14 20:55:47.641568+0200 0x25321    Debug       0x0                  14552  0    java: (keychain-pkcs11.dylib) [mil.navy.nrl.cmf.pkcs11:general] tokens_present = true, slot_list = 0x60000255c680, slot_num = 0
2022-09-14 20:55:47.641587+0200 0x25321    Debug       0x0                  14552  0    java: (keychain-pkcs11.dylib) [mil.navy.nrl.cmf.pkcs11:general] C_GetSlotList returning CKR_OK

Here some commands to determine my context:

➜  ~ security smartcards token -l
# (previous command return nothing)
➜  ~ sudo security smartcards token -e com.apple.CryptoTokenKit.pivtoken
Token is already enabled.
➜  ~ sw_vers
ProductName:    macOS
ProductVersion: 12.6
BuildVersion:   21G115

Do you know what's wrong?

kenh commented 2 years ago

I think there are two separate things going wrong.

First, this:

Caused by: java.security.ProviderException: slotListIndex is 0 but token only has 0 slots

I am willing to believe I got something wrong here, but I am not completely sure that I did. I am not sure if I did. It asks for the number of slots available if tokens are present (it first asks for all slots even without tokens, and that count should always be at least 1). And ... well, that leads to problem number two:

2022-09-14 20:55:47.625206+0200 0x25321 Debug 0x0 14552 0 java: (keychain-pkcs11.dylib) [mil.navy.nrl.cmf.pkcs11:general] Looking for identities for token com.apple.setoken 2022-09-14 20:55:47.627565+0200 0x25321 Debug 0x0 14552 0 java: (keychain-pkcs11.dylib) [mil.navy.nrl.cmf.pkcs11:general] No identities found 2022-09-14 20:55:47.627644+0200 0x25321 Debug 0x0 14552 0 java: (keychain-pkcs11.dylib) [mil.navy.nrl.cmf.pkcs11:general] Looking for identities for token com.apple.setoken:aks 2022-09-14 20:55:47.628745+0200 0x25321 Debug 0x0 14552 0 java: (keychain-pkcs11.dylib) [mil.navy.nrl.cmf.pkcs11:general] No identities found 2022-09-14 20:55:47.628858+0200 0x25321 Debug 0x0 14552 0 java: (keychain-pkcs11.dylib) [mil.navy.nrl.cmf.pkcs11:general] C_Initalize returning CKR_OK

This tells me it didn't find any identities.

So this is something not everyone completely understands about Keychain-PKCS11 ... it was designed to work only with HARDWARE tokens. It uses the TkToken interface to only get hardware identities. It doesn't get ALL identities that are found in the Keychain. It is possible by setting a special preferences item to get CERTIFICATES exposed as another slot, but that is certificates only; you don't get a full identity and you can't perform crypto operations on them. That's mostly useful for things like Firefox to get certificates from the Keychain.

I've thought about adding the functionality to create another slot that lets you use any identity found in the Keychain, but I haven't done that yet.