Closed mouse07410 closed 8 years ago
PKCS11_enumerate_keys calls both: pkcs11_find_keys(token, CKO_PRIVATE_KEY) pkcs11_find_keys(token, CKO_PUBLIC_KEY)
Best I can tell without a debugger, it returns an array of all the keys, but the count is just the private keys. It also looks like it expects at least one private key, and one public key, but that should be debugged too.
looks for both private and public keys. and save the list in the token
looks for both private and public keys. and save the list in the token
Thank you! I think this is the problem, as it breaks PIN-less usage of public key by OpenSSL. Instead of performing signature verification, it replies with "key not found".
PKCS11_enumerate_keys()
defined? I seemed unable to locate it in the source of either engine_pkcs11
or OpenSC
. (?!) Update _I found a strange library /Library/OpenSC/lib/engines/engine_pkcs11.so
dated a few months back. That library contains the entry points in question. I also found those entry points defined in /opt/local/lib/libp11.dylib
, which is probably what should be used._engine_pckcs11
call pkcs11_find_keys(token, CKO_PUBLIC_KEY)
itself, when the request is for a public key???Update 2
I've turned on verbose in engine_pkcs11
, and observe that the list received by it from PKCS11_enumerate_keys()
only contains private keys. There is no mention of the corresponding public keys in the verbose printout. More so, I got to the source of libp11
(Github mirror), and found this:
/*
* Enumerate all keys on the card
* For now, we enumerate just the private keys.
*/
int
PKCS11_enumerate_keys(PKCS11_TOKEN * token, PKCS11_KEY ** keyp, unsigned int *countp)
{
PKCS11_TOKEN_private *priv = PRIVTOKEN(token);
if (priv->nkeys < 0) {
priv->nkeys = 0;
if (pkcs11_find_keys(token, CKO_PRIVATE_KEY)) {
pkcs11_destroy_keys(token);
return -1;
}
priv->nprkeys = priv->nkeys;
if (pkcs11_find_keys(token, CKO_PUBLIC_KEY)) {
pkcs11_destroy_keys(token);
return -1;
}
}
*keyp = priv->keys;
*countp = priv->nprkeys;
return 0;
}
That means I need to (a) modify the key retrieval in engine_pkcs11.c
, and (b) add something like PKCS11_enumerate_public_keys()
to libp11. Nice...
Some of the changes may have been made recently to fix memory leaks. Anyone know if this is true?
The way I read the code is PKCS11_enumerate_keys calls pkcs11_find_keys(token, CKO_PRIVATE_KEY) pkcs11_find_keys(token, CKO_PUBLIC_KEY)
They both call pkcs11_next_key that calls pkcs11_init_key. pkcs11_init_key uses OpenSSL_realloc to for each key,
so when all done priv = PRIVTOKEN(token); priv->keys is
a pointer to an arrry of the pprivate and public keys of size priv->nkeys.
There seems to be a ton of memory leaks still around that code.
Also, when I tried to modify PKCS11_enumerate_keys()
to return both private and public keys, it magically stopped working...
Here's an example of what happens when I change in libp11 in PKCS11_enumerate_keys()
the number of keys it reports it found:
$ pkcs11-ecdsa-demo winconfig.h
openssl dgst -engine pkcs11 -keyform engine -sha384 -sign id_02 -out /tmp/winconfig.h.sig winconfig.h
initializing engine
engine "pkcs11" set.
Looking in slot -1 for key: 02
Found 2 slots
[18446744073709551615] Virtual hotplug slot no tok
[1] Yubico Yubikey 4 OTP+U2F+ login (PIV_II (PIV Card Holder pin))
Found slot: Yubico Yubikey 4 OTP+U2F+CCID
Found token: PIV_II (PIV Card Holder pin)
Found 4 certificates:
1 Certificate for PIV Authentication (/CN=Uri the Great)
2 Certificate for Digital Signature (/CN=Uri the Great)
3 Certificate for Key Management (/CN=Uri the Great)
4 Certificate for Card Authentication (/CN=Uri the Great)
PKCS#11 token PIN:
Found 4 keys:
1 P PIV AUTH key
2 P SIGN key
3 P KEY MAN key
4 P CARD AUTH key
Signature for winconfig.h is stored in /tmp/winconfig.h.sig
pkcs11-tool -r -y pubkey -d 02 -o /tmp/derive.39901.02
Using slot 1 with a present token (0x1)
openssl dgst -verify /tmp/derive.39901.02 -keyform DER -sha384 -signature /tmp/winconfig.h.sig < winconfig.h
Verified OK
openssl dgst -engine pkcs11 -keyform engine -sha384 -verify id_02 -signature /tmp/winconfig.h.sig < winconfig.h
initializing engine
engine "pkcs11" set.
Looking in slot -1 for key: 02
Found 2 slots
[18446744073709551615] Virtual hotplug slot no tok
[1] Yubico Yubikey 4 OTP+U2F+ login (PIV_II (PIV Card Holder pin))
Found slot: Yubico Yubikey 4 OTP+U2F+CCID
Found token: PIV_II (PIV Card Holder pin)
Found 4 certificates:
1 Certificate for PIV Authentication (/CN=Uri the Great)
2 Certificate for Digital Signature (/CN=Uri the Great)
3 Certificate for Key Management (/CN=Uri the Great)
4 Certificate for Card Authentication (/CN=Uri the Great)
PKCS#11 token PIN:
Found 4 keys:
1 P PIV AUTH key
2 P SIGN key
3 P KEY MAN key
4 P CARD AUTH key
Verified OK
$ pkcs11-ecdsa-demo winconfig.h
openssl dgst -engine pkcs11 -keyform engine -sha384 -sign id_02 -out /tmp/winconfig.h.sig winconfig.h
initializing engine
engine "pkcs11" set.
Looking in slot -1 for key: 02
Found 2 slots
[18446744073709551615] Virtual hotplug slot no tok
[1] Yubico Yubikey 4 OTP+U2F+ login (PIV_II (PIV Card Holder pin))
Found slot: Yubico Yubikey 4 OTP+U2F+CCID
Found token: PIV_II (PIV Card Holder pin)
Found 4 certificates:
1 Certificate for PIV Authentication (/CN=Uri the Great)
2 Certificate for Digital Signature (/CN=Uri the Great)
3 Certificate for Key Management (/CN=Uri the Great)
4 Certificate for Card Authentication (/CN=Uri the Great)
PKCS#11 token PIN:
Found 8 keys:
1 P PIV AUTH key
2 P SIGN key
3 P KEY MAN key
4 P CARD AUTH key
5 PIV AUTH pubkey
6 SIGN pubkey
7 KEY MAN pubkey
8 CARD AUTH pubkey
Error Signing Data
140735231131728:error:80029063:PKCS11 library:func(41):bad key parameters format:p11_ops.c:62:
Signature for winconfig.h is stored in /tmp/winconfig.h.sig
pkcs11-tool -r -y pubkey -d 02 -o /tmp/derive.40409.02
Using slot 1 with a present token (0x1)
openssl dgst -verify /tmp/derive.40409.02 -keyform DER -sha384 -signature /tmp/winconfig.h.sig < winconfig.h
Error reading signature file /tmp/winconfig.h.sig
openssl dgst -engine pkcs11 -keyform engine -sha384 -verify id_02 -signature /tmp/winconfig.h.sig < winconfig.h
initializing engine
engine "pkcs11" set.
Looking in slot -1 for key: 02
Found 2 slots
[18446744073709551615] Virtual hotplug slot no tok
[1] Yubico Yubikey 4 OTP+U2F+ login (PIV_II (PIV Card Holder pin))
Found slot: Yubico Yubikey 4 OTP+U2F+CCID
Found token: PIV_II (PIV Card Holder pin)
Found 4 certificates:
1 Certificate for PIV Authentication (/CN=Uri the Great)
2 Certificate for Digital Signature (/CN=Uri the Great)
3 Certificate for Key Management (/CN=Uri the Great)
4 Certificate for Card Authentication (/CN=Uri the Great)
PKCS#11 token PIN:
Found 8 keys:
1 P PIV AUTH key
2 P SIGN key
3 P KEY MAN key
4 P CARD AUTH key
5 PIV AUTH pubkey
6 SIGN pubkey
7 KEY MAN pubkey
8 CARD AUTH pubkey
Error reading signature file /tmp/winconfig.h.sig
Hmm... I think I fixed engine_pkcs11
and libp11
, at least with respect to not prompting for PIN when only public key operation is required (such as by OpenSSL). Still a lot more work is necessary, but it is promising (debugging output):
$ pkcs11-rsa-pss-sign-demo winconfig.h
openssl dgst -engine pkcs11 -keyform engine -sign "pkcs11:object=SIGN%20key;object-type=private;pin-value=123456" -sha384 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 -out winconfig.h.sig winconfig.h
initializing engine
engine "pkcs11" set.
Looking in slot -1 for key: label: SIGN key
Found 2 slots
[18446744073709551615] Virtual hotplug slot no tok
[1] Yubico Yubikey NEO OTP+U2 login (PIV_II (PIV Card Holder pin))
Found slot: Yubico Yubikey NEO OTP+U2F+CCID
Found token: PIV_II (PIV Card Holder pin)
Found 4 certificates:
1 Certificate for PIV Authentication (/CN=Mouse Mousevich)
2 Certificate for Digital Signature (/emailAddress=mouse07410@outlook.com/CN=Mouse Mousevich)
3 Certificate for Key Management (/emailAddress=mouse07410@outlook.com/CN=Mouse Mousevich)
4 Certificate for Card Authentication (/CN=Mouse Mousevich)
PKCS#11 token PIN:
Found 8 keys:
1 P PIV AUTH key
2 P SIGN key
3 P KEY MAN key
4 P CARD AUTH key
5 PIV AUTH pubkey
6 SIGN pubkey
7 KEY MAN pubkey
8 CARD AUTH pubkey
Signature for winconfig.h is stored in winconfig.h.sig
pkcs11-tool -r -y pubkey -d 02 -o /tmp/derive.43856.pubkey.02
Using slot 1 with a present token (0x1)
openssl dgst -verify /tmp/derive.43856.pubkey.02 -keyform DER -sha384 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 -signature winconfig.h.sig < winconfig.h
Verified OK
openssl dgst -engine pkcs11 -keyform engine -sha384 -verify id_02 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 -signature winconfig.h.sig winconfig.h
initializing engine
engine "pkcs11" set.
Looking in slot -1 for key: 02
Found 2 slots
[18446744073709551615] Virtual hotplug slot no tok
[1] Yubico Yubikey NEO OTP+U2 login (PIV_II (PIV Card Holder pin))
Found slot: Yubico Yubikey NEO OTP+U2F+CCID
Found token: PIV_II (PIV Card Holder pin)
Found 4 certificates:
1 Certificate for PIV Authentication (/CN=Mouse Mousevich)
2 Certificate for Digital Signature (/emailAddress=mouse07410@outlook.com/CN=Mouse Mousevich)
3 Certificate for Key Management (/emailAddress=mouse07410@outlook.com/CN=Mouse Mousevich)
4 Certificate for Card Authentication (/CN=Mouse Mousevich)
Found 4 public keys:
1 PIV AUTH pubkey
2 SIGN pubkey
3 KEY MAN pubkey
4 CARD AUTH pubkey
Verified OK
The above works for RSA. So far so good. Now, trying ECDSA, the same code fails miserably:
pkcs11-ecdsa-demo winconfig.h
openssl dgst -engine pkcs11 -keyform engine -sha384 -sign pkcs11:object=SIGN%20key
/Users/uri/bin/pkcs11-ecdsa-demo: line 52: object-type=private -out /tmp/winconfig.h.sig winconfig.h: No such file or directory
initializing engine
engine "pkcs11" set.
Looking in slot -1 for key: label: SIGN key
Found 2 slots
[18446744073709551615] Virtual hotplug slot no tok
[1] Yubico Yubikey 4 OTP+U2F+ login (PIV_II (PIV Card Holder pin))
Found slot: Yubico Yubikey 4 OTP+U2F+CCID
Found token: PIV_II (PIV Card Holder pin)
Found 4 certificates:
1 Certificate for PIV Authentication (/CN=Uri the Great)
2 Certificate for Digital Signature (/CN=Uri the Great)
3 Certificate for Key Management (/CN=Uri the Great)
4 Certificate for Card Authentication (/CN=Uri the Great)
PKCS#11 token PIN:
Found 8 keys:
1 P PIV AUTH key
2 P SIGN key
3 P KEY MAN key
4 P CARD AUTH key
5 PIV AUTH pubkey
6 SIGN pubkey
7 KEY MAN pubkey
8 CARD AUTH pubkey
Signature for winconfig.h is stored in /tmp/winconfig.h.sig
pkcs11-tool -r -y pubkey -d 02 -o /tmp/derive.45235.02
Using slot 1 with a present token (0x1)
openssl dgst -verify /tmp/derive.45235.02 -keyform DER -sha384 -signature /tmp/winconfig.h.sig < winconfig.h
Verified OK
openssl dgst -engine pkcs11 -keyform engine -sha384 -verify pkcs11:object=SIGN%20pubkey
/Users/uri/bin/pkcs11-ecdsa-demo: line 70: object-type=public -signature /tmp/winconfig.h.sig < winconfig.h: No such file or directory
initializing engine
engine "pkcs11" set.
Looking in slot -1 for key: label: SIGN pubkey
Found 2 slots
[18446744073709551615] Virtual hotplug slot no tok
[1] Yubico Yubikey 4 OTP+U2F+ login (PIV_II (PIV Card Holder pin))
Found slot: Yubico Yubikey 4 OTP+U2F+CCID
Found token: PIV_II (PIV Card Holder pin)
Found 4 certificates:
1 Certificate for PIV Authentication (/CN=Uri the Great)
2 Certificate for Digital Signature (/CN=Uri the Great)
3 Certificate for Key Management (/CN=Uri the Great)
4 Certificate for Card Authentication (/CN=Uri the Great)
Found 4 public keys:
1 PIV AUTH pubkey
2 SIGN pubkey
3 KEY MAN pubkey
4 CARD AUTH pubkey
Out of memory
140735231131728:error:10098043:elliptic curve routines:o2i_ECPublicKey:passed a null parameter:ec_asn1.c:1271:
Returning to having engine_pkcs11
always unlock the token and enumerate all the keys (including private) all the time, it works for ECDSA as well:
pkcs11-ecdsa-demo winconfig.h
openssl dgst -engine pkcs11 -keyform engine -sha384 -sign pkcs11:object=SIGN%20key
/Users/uri/bin/pkcs11-ecdsa-demo: line 52: object-type=private -out /tmp/winconfig.h.sig winconfig.h: No such file or directory
initializing engine
engine "pkcs11" set.
Looking in slot -1 for key: label: SIGN key
Found 2 slots
[18446744073709551615] Virtual hotplug slot no tok
[1] Yubico Yubikey 4 OTP+U2F+ login (PIV_II (PIV Card Holder pin))
Found slot: Yubico Yubikey 4 OTP+U2F+CCID
Found token: PIV_II (PIV Card Holder pin)
Found 4 certificates:
1 Certificate for PIV Authentication (/CN=Uri the Great)
2 Certificate for Digital Signature (/CN=Uri the Great)
3 Certificate for Key Management (/CN=Uri the Great)
4 Certificate for Card Authentication (/CN=Uri the Great)
PKCS#11 token PIN:
Found 8 keys:
1 P PIV AUTH key
2 P SIGN key
3 P KEY MAN key
4 P CARD AUTH key
5 PIV AUTH pubkey
6 SIGN pubkey
7 KEY MAN pubkey
8 CARD AUTH pubkey
Signature for winconfig.h is stored in /tmp/winconfig.h.sig
pkcs11-tool -r -y pubkey -d 02 -o /tmp/derive.45411.02
Using slot 1 with a present token (0x1)
openssl dgst -verify /tmp/derive.45411.02 -keyform DER -sha384 -signature /tmp/winconfig.h.sig < winconfig.h
Verified OK
openssl dgst -engine pkcs11 -keyform engine -sha384 -verify pkcs11:object=SIGN%20pubkey
/Users/uri/bin/pkcs11-ecdsa-demo: line 70: object-type=public -signature /tmp/winconfig.h.sig < winconfig.h: No such file or directory
initializing engine
engine "pkcs11" set.
Looking in slot -1 for key: label: SIGN pubkey
Found 2 slots
[18446744073709551615] Virtual hotplug slot no tok
[1] Yubico Yubikey 4 OTP+U2F+ login (PIV_II (PIV Card Holder pin))
Found slot: Yubico Yubikey 4 OTP+U2F+CCID
Found token: PIV_II (PIV Card Holder pin)
Found 4 certificates:
1 Certificate for PIV Authentication (/CN=Uri the Great)
2 Certificate for Digital Signature (/CN=Uri the Great)
3 Certificate for Key Management (/CN=Uri the Great)
4 Certificate for Card Authentication (/CN=Uri the Great)
PKCS#11 token PIN:
Found 8 keys:
1 P PIV AUTH key
2 P SIGN key
3 P KEY MAN key
4 P CARD AUTH key
5 PIV AUTH pubkey
6 SIGN pubkey
7 KEY MAN pubkey
8 CARD AUTH pubkey
Verified OK
Needless to say, I'd appreciate some guidance here. Looks like we're close. After all, it work properly for RSA...
openssl dgst -engine pkcs11 -keyform engine -sha384 -verify pkcs11:object=SIGN%20pubkey /Users/uri/bin/pkcs11-ecdsa-demo: line 70: object-type=public -signature /tmp/winconfig.h.sig < winconfig.h: No such file or directory
Looks like an error in your script. The parameter is not quoted so ";" in parameter is taken as end of comand.
You're correct. Fixing the script brings this:
$ openssl dgst -engine pkcs11 -keyform engine -sha384 -sign "pkcs11:object=SIGN%20key;object-type=private" -out t.sig winconfig.h
initializing engine
engine "pkcs11" set.
Looking in slot -1 for key: label: SIGN key
Found 2 slots
[18446744073709551615] Virtual hotplug slot no tok
[1] Yubico Yubikey 4 OTP+U2F+ login (PIV_II (PIV Card Holder pin))
Found slot: Yubico Yubikey 4 OTP+U2F+CCID
Found token: PIV_II (PIV Card Holder pin)
Found 4 certificates:
1 Certificate for PIV Authentication (/CN=Uri the Great)
2 Certificate for Digital Signature (/CN=Uri the Great)
3 Certificate for Key Management (/CN=Uri the Great)
4 Certificate for Card Authentication (/CN=Uri the Great)
PKCS#11 token PIN:
Found 8 keys:
1 P PIV AUTH key
2 P SIGN key
3 P KEY MAN key
4 P CARD AUTH key
5 PIV AUTH pubkey
6 SIGN pubkey
7 KEY MAN pubkey
8 CARD AUTH pubkey
Private-Key: (384 bit)
pub:
04:32:3d:ac:5d:34:44:9a:c1:70:73:d5:ee:de:c1:
53:26:48:da:7e:19:04:c7:70:3a:a4:38:4b:fd:60:
d4:ca:ab:4d:f5:0b:cf:d3:d4:2d:d4:d0:da:15:97:
32:c1:2b:d6:01:64:70:05:da:35:f5:cf:16:c4:a3:
67:4a:59:15:4c:a2:e6:6d:8e:e8:1e:11:5c:4a:9b:
e8:9c:21:fc:19:b2:9f:0f:99:1b:f0:82:39:d0:08:
15:63:44:35:09:08:f9
ASN1 OID: secp384r1
NIST CURVE: P-384
Illegal instruction: 4
How about a dump, showing were the Illegal instruction is at?
Can your run gdb in the command?
Do you build the packages with debugging? i.e. CFLAGS=-g LDFLAGS=-g
How about a dump, showing were the Illegal instruction is at?
It looks to me like the crash occurs in the call to key_getattr_var()
:
$ openssl dgst -engine pkcs11 -keyform engine -sha384 -sign "pkcs11:object=SIGN%20key;object-type=private" -out t.sig stamp-h1
initializing engine
engine "pkcs11" set.
Looking in slot -1 for key: label: SIGN key
Found 2 slots
[18446744073709551615] Virtual hotplug slot no tok
[1] Yubico Yubikey 4 OTP+U2F+ login (PIV_II (PIV Card Holder pin))
Found slot: Yubico Yubikey 4 OTP+U2F+CCID
Found token: PIV_II (PIV Card Holder pin)
Found 4 certificates:
1 Certificate for PIV Authentication (/CN=Uri the Great)
2 Certificate for Digital Signature (/CN=Uri the Great)
3 Certificate for Key Management (/CN=Uri the Great)
4 Certificate for Card Authentication (/CN=Uri the Great)
PKCS#11 token PIN:
Found 8 keys:
1 P PIV AUTH key
2 P SIGN key
3 P KEY MAN key
4 P CARD AUTH key
5 PIV AUTH pubkey
6 SIGN pubkey
7 KEY MAN pubkey
8 CARD AUTH pubkey
Private-Key: (384 bit)
pub:
04:32:3d:ac:5d:34:44:9a:c1:70:73:d5:ee:de:c1:
53:26:48:da:7e:19:04:c7:70:3a:a4:38:4b:fd:60:
d4:ca:ab:4d:f5:0b:cf:d3:d4:2d:d4:d0:da:15:97:
32:c1:2b:d6:01:64:70:05:da:35:f5:cf:16:c4:a3:
67:4a:59:15:4c:a2:e6:6d:8e:e8:1e:11:5c:4a:9b:
e8:9c:21:fc:19:b2:9f:0f:99:1b:f0:82:39:d0:08:
15:63:44:35:09:08:f9
ASN1 OID: secp384r1
NIST CURVE: P-384
pkcs11_get_ec_public(): pk->type == EVP_PKEY_EC
about to call key_getattr_var(pubkey, CKA_EC_POINT, NULL, &ec_pointlen)
Illegal instruction: 4
Does this help (please feel free to edit what's irrelevant, or tell me what parts of this long log to prune):
Process: openssl [53738]
Path: /opt/local/bin/openssl
Identifier: openssl
Version: 0
Code Type: X86-64 (Native)
Parent Process: bash [798]
Responsible: iTerm [745]
User ID: 501
Date/Time: 2015-12-29 17:21:51.885 -0500
OS Version: Mac OS X 10.11.2 (15C50)
Report Version: 11
Anonymous UUID: B3544DF6-AE65-3AD0-0E52-DD6C16797F5A
Sleep/Wake UUID: CCA9BD97-1EF4-4132-B51C-13F38644F395
Time Awake Since Boot: 71000 seconds
Time Since Wake: 15000 seconds
System Integrity Protection: enabled
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Exception Type: EXC_BAD_INSTRUCTION (SIGILL)
Exception Codes: 0x0000000000000001, 0x0000000000000000
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 libp11.2.dylib 0x000000010e0e9541 pkcs11_get_ec_public + 129
1 libp11.2.dylib 0x000000010e0e7ebd PKCS11_get_private_key + 77
2 libpkcs11.dylib 0x000000010e0e05ed pkcs11_load_key + 3485
3 libpkcs11.dylib 0x000000010e0e077a pkcs11_load_private_key + 26
4 libcrypto.1.0.0.dylib 0x000000010dd421ed ENGINE_load_private_key + 125
5 openssl 0x000000010dbe00de load_key + 110
6 openssl 0x000000010dbb2191 dgst_main + 3217
7 openssl 0x000000010dbabb0d do_cmd + 141
8 openssl 0x000000010dbab980 main + 1280
9 libdyld.dylib 0x00007fff8e35c5ad start + 1
Thread 1:
0 libsystem_kernel.dylib 0x00007fff9e32b6de __workq_kernreturn + 10
1 libsystem_pthread.dylib 0x00007fff8f8ef729 _pthread_wqthread + 1283
2 libsystem_pthread.dylib 0x00007fff8f8ed365 start_wqthread + 13
Thread 2:: Dispatch queue: com.apple.libdispatch-manager
0 libsystem_kernel.dylib 0x00007fff9e32bff6 kevent_qos + 10
1 libdispatch.dylib 0x00007fff90a0e099 _dispatch_mgr_invoke + 216
2 libdispatch.dylib 0x00007fff90a0dd01 _dispatch_mgr_thread + 52
Thread 3:
0 libsystem_kernel.dylib 0x00007fff9e32b6de __workq_kernreturn + 10
1 libsystem_pthread.dylib 0x00007fff8f8ef729 _pthread_wqthread + 1283
2 libsystem_pthread.dylib 0x00007fff8f8ed365 start_wqthread + 13
Thread 0 crashed with X86 Thread State (64-bit):
rax: 0x0000000000000001 rbx: 0x00007f9f7bf01cc0 rcx: 0x0000e4000000e503 rdx: 0x0000e5000000e500
rdi: 0x00007fff78c311e8 rsi: 0x0000000000012068 rbp: 0x00007fff52054860 rsp: 0x00007fff52054850
r8: 0x0000000000000040 r9: 0x00007fff78c311e0 r10: 0xffffffffffffffff r11: 0x0000000000000246
r12: 0x0000000000000180 r13: 0x00007f9f7bf02810 r14: 0x00007f9f7bf01cc0 r15: 0x00007f9f7bf01d00
rip: 0x000000010e0e9541 rfl: 0x0000000000010206 cr2: 0x000000010dd20000
Logical CPU: 0
Error Code: 0x00000000
Trap Number: 6
Binary Images:
0x10dbaa000 - 0x10dc15ff7 +openssl (0) <051F2A34-1FFB-3E51-9141-9111A7959B3D> /opt/local/bin/openssl
0x10dc3a000 - 0x10dc83fff +libssl.1.0.0.dylib (0) <180A5699-8713-3E3F-82D1-64862243EA61> /opt/local/lib/libssl.1.0.0.dylib
0x10dca2000 - 0x10de20e67 +libcrypto.1.0.0.dylib (0) <F612E758-7FD4-3ECD-BE33-A00BCE0DAA0A> /opt/local/lib/libcrypto.1.0.0.dylib
0x10de9c000 - 0x10deacfff +libz.1.dylib (0) <5FCFF38B-5983-3590-B5E9-074CF0950676> /opt/local/lib/libz.1.dylib
0x10e0de000 - 0x10e0e1fff +libpkcs11.dylib (0) <ECD88537-61E6-3EBB-B0C5-822C0D76B129> /opt/local/lib/*/libpkcs11.dylib
0x10e0e5000 - 0x10e0ebfff +libp11.2.dylib (0) <5105E0C6-EA1F-393E-B616-ACB814772E81> /opt/local/lib/libp11.2.dylib
0x10e0f0000 - 0x10e11cfff +opensc-pkcs11.so (0) <5C1386C2-771A-3545-BCA4-F795B82EF72F> /Library/OpenSC/*/opensc-pkcs11.so
0x10e129000 - 0x10e338fff +libopensc.4.dylib (0) <FFAE6B40-0725-3467-B426-DA7185DE871F> /Library/OpenSC/*/libopensc.4.dylib
0x10e374000 - 0x10e383fff +libgost.dylib (0) <F4F0C018-1BF1-3086-80BF-E429BD54A131> /opt/local/lib/*/libgost.dylib
0x7fff6a5bb000 - 0x7fff6a5f1fa7 dyld (360.18) <1A7F8274-FC32-3B86-9979-66B8F2B7B5E2> /usr/lib/dyld
0x7fff87e1c000 - 0x7fff87e1dfff libsystem_secinit.dylib (20) <FD6ECF2C-1489-32CA-981B-9045B5EB1FAA> /usr/lib/system/libsystem_secinit.dylib
0x7fff88935000 - 0x7fff88988ff7 libc++.1.dylib (120.1) <8FC3D139-8055-3498-9AC5-6467CB7F4D14> /usr/lib/libc++.1.dylib
0x7fff89b87000 - 0x7fff89b88ffb libremovefile.dylib (41) <B8D1A5FC-CFD5-3AAB-8A10-14DDC129710A> /usr/lib/system/libremovefile.dylib
0x7fff89c6e000 - 0x7fff89c76fff libcopyfile.dylib (127) <F5133269-0B22-388C-A57C-079667B6291E> /usr/lib/system/libcopyfile.dylib
0x7fff8a343000 - 0x7fff8a346ff7 libsystem_sandbox.dylib (460.20.9) <1C891336-1B25-365D-B43E-96D5B3BE66B0> /usr/lib/system/libsystem_sandbox.dylib
0x7fff8a36a000 - 0x7fff8a3f7fff libsystem_c.dylib (1082.20.4) <EAB38A6C-8671-3B13-B500-90EC1B912063> /usr/lib/system/libsystem_c.dylib
0x7fff8a47f000 - 0x7fff8a47fff7 libkeymgr.dylib (28) <09397E01-6066-3179-A50C-2CE666FDA929> /usr/lib/system/libkeymgr.dylib
0x7fff8ada6000 - 0x7fff8adb0fff com.apple.pcsc (8.0 - 1) <A6974721-8A6A-361B-8CC5-C57809E1B985> /System/Library/Frameworks/PCSC.framework/Versions/A/PCSC
0x7fff8adbe000 - 0x7fff8adc3ff3 libunwind.dylib (35.3) <124E0F05-2350-3774-A32C-7F5BF38EDE73> /usr/lib/system/libunwind.dylib
0x7fff8ba0b000 - 0x7fff8ba14ff3 libsystem_notify.dylib (150.20.3) <243FADE1-255A-3B78-8033-F336CD64B817> /usr/lib/system/libsystem_notify.dylib
0x7fff8e299000 - 0x7fff8e2a4ff7 libcommonCrypto.dylib (60075.20.1) <766BC3F5-41F3-3315-BABC-72718A98EA92> /usr/lib/system/libcommonCrypto.dylib
0x7fff8e359000 - 0x7fff8e35cffb libdyld.dylib (360.18) <5F3777A7-F07E-3D5F-BFA3-A920FF4170ED> /usr/lib/system/libdyld.dylib
0x7fff8f8ec000 - 0x7fff8f8f5ff7 libsystem_pthread.dylib (138.10.4) <327CECD0-B881-3153-8FCC-4FD4818B7F16> /usr/lib/system/libsystem_pthread.dylib
0x7fff8fab2000 - 0x7fff8fab4ff7 libquarantine.dylib (80) <163CF63A-7455-3D1F-AE57-8C4475A9204C> /usr/lib/system/libquarantine.dylib
0x7fff8fee4000 - 0x7fff9035afff com.apple.CoreFoundation (6.9 - 1256.14) <068D1BA9-3859-34C7-986A-97EDF739C5C8> /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
0x7fff90a06000 - 0x7fff90a33fff libdispatch.dylib (501.20.1) <324C9189-2AF3-3356-847F-6F4CE1C6E901> /usr/lib/system/libdispatch.dylib
0x7fff90a95000 - 0x7fff90abefff libsystem_info.dylib (477.20.1) <6513635B-4ADE-3B45-BF63-ED7AC565B0C9> /usr/lib/system/libsystem_info.dylib
0x7fff92b8a000 - 0x7fff92b8bfff libDiagnosticMessagesClient.dylib (100) <4243B6B4-21E9-355B-9C5A-95A216233B96> /usr/lib/libDiagnosticMessagesClient.dylib
0x7fff92ec6000 - 0x7fff92eeffff libxpc.dylib (756.20.4) <61AB4610-9304-354C-9E9B-D57198AE9866> /usr/lib/system/libxpc.dylib
0x7fff92ef0000 - 0x7fff92f36ff7 libauto.dylib (186) <999E610F-41FC-32A3-ADCA-5EC049B65DFB> /usr/lib/libauto.dylib
0x7fff934a3000 - 0x7fff934b4ff7 libz.1.dylib (61.20.1) <B3EBB42F-48E3-3287-9F0D-308E04D407AC> /usr/lib/libz.1.dylib
0x7fff93c09000 - 0x7fff93e16ffb libicucore.A.dylib (551.41) <CFFD7342-A7D6-323A-AC14-B9EECF6EFFED> /usr/lib/libicucore.A.dylib
0x7fff94ac9000 - 0x7fff94ae5ff7 libsystem_malloc.dylib (67) <9EECAB18-F025-34C4-8E32-7EFFA6720EFC> /usr/lib/system/libsystem_malloc.dylib
0x7fff94ae6000 - 0x7fff94ae7ffb libSystem.B.dylib (1226.10.1) <54388DF0-3813-33E4-BE8D-7743A81ACF4D> /usr/lib/libSystem.B.dylib
0x7fff958ae000 - 0x7fff958b0fff libsystem_coreservices.dylib (19.2) <1B3F5AFC-FFCD-3ECB-8B9A-5538366FB20D> /usr/lib/system/libsystem_coreservices.dylib
0x7fff960db000 - 0x7fff960e2ff7 libcompiler_rt.dylib (62) <D3C4AB40-23B4-3BC6-8C38-5B8758D14E80> /usr/lib/system/libcompiler_rt.dylib
0x7fff96148000 - 0x7fff96149fff libsystem_blocks.dylib (65) <49D42329-7DE9-3413-92C3-A473A7E9CF35> /usr/lib/system/libsystem_blocks.dylib
0x7fff96b42000 - 0x7fff96b42ff7 liblaunch.dylib (756.20.4) <EDF719D6-D2BB-38DD-8C94-4272BEFDA2CD> /usr/lib/system/liblaunch.dylib
0x7fff96f5b000 - 0x7fff96f84fff libc++abi.dylib (125) <DCCC8177-3D09-35BC-9784-2A04FEC4C71B> /usr/lib/libc++abi.dylib
0x7fff978ea000 - 0x7fff9794bff7 libsystem_network.dylib (583.20.10) <1C0410F3-F66E-3B0D-B8AD-0D49AB15A529> /usr/lib/system/libsystem_network.dylib
0x7fff97e0a000 - 0x7fff97e0efff libcache.dylib (75) <6B245C0A-F3EA-383B-A542-5B0D0456A41B> /usr/lib/system/libcache.dylib
0x7fff98852000 - 0x7fff98869fff libsystem_asl.dylib (322) <3C2D3ACD-0DD1-337A-8247-44A910D67A65> /usr/lib/system/libsystem_asl.dylib
0x7fff99eac000 - 0x7fff99ec2ff7 libsystem_coretls.dylib (83.20.8) <30AF7134-6CA7-3582-B9D3-507D6ED19A88> /usr/lib/system/libsystem_coretls.dylib
0x7fff99f55000 - 0x7fff9a2b7f3f libobjc.A.dylib (680) <9F45830D-F1D5-3CDF-9461-1A5477ED7D1E> /usr/lib/libobjc.A.dylib
0x7fff9a2e2000 - 0x7fff9a2eafe7 libsystem_platform.dylib (74.10.3) <D3A27E10-7F08-3603-ACC8-7A92B2C04BAB> /usr/lib/system/libsystem_platform.dylib
0x7fff9a338000 - 0x7fff9a33dff7 libmacho.dylib (875.1) <CB745E1F-4885-3F96-B38B-2093DF488FD5> /usr/lib/system/libmacho.dylib
0x7fff9a5f2000 - 0x7fff9a5faffb libsystem_dnssd.dylib (625.20.4) <945B5FB1-DA91-3D45-A961-A8FAD53C1E7E> /usr/lib/system/libsystem_dnssd.dylib
0x7fff9aeb4000 - 0x7fff9aebcfff libsystem_networkextension.dylib (385.20.6) <DC8A102A-BF02-31A4-8914-65C34DF6B592> /usr/lib/system/libsystem_networkextension.dylib
0x7fff9c799000 - 0x7fff9c799ff7 libunc.dylib (29) <1D0F8265-F026-3CBD-93D3-F8DF14FFCE68> /usr/lib/system/libunc.dylib
0x7fff9c79a000 - 0x7fff9c7abff7 libsystem_trace.dylib (201.10.3) <F0B7622B-FB6B-31E1-8703-38F57BE84553> /usr/lib/system/libsystem_trace.dylib
0x7fff9ca64000 - 0x7fff9ca66ff7 libsystem_configuration.dylib (802.20.7) <5FD79070-36CC-3D02-BEA7-BB5D2AE97D5D> /usr/lib/system/libsystem_configuration.dylib
0x7fff9ce8a000 - 0x7fff9cf01fe7 libcorecrypto.dylib (335.20.1) <C6BD205F-4ECE-37EE-BCAB-A76F39CDCFFA> /usr/lib/system/libcorecrypto.dylib
0x7fff9e1b2000 - 0x7fff9e1e1ffb libsystem_m.dylib (3105) <26655445-CA97-321E-B221-801CB378D1AA> /usr/lib/system/libsystem_m.dylib
0x7fff9e314000 - 0x7fff9e332fff libsystem_kernel.dylib (3248.20.55) <0E688457-4915-36DD-8798-5C2EDEE3F1A3> /usr/lib/system/libsystem_kernel.dylib
External Modification Summary:
Calls made by other processes targeting this process:
task_for_pid: 1
thread_create: 0
thread_set_state: 0
Calls made by this process:
task_for_pid: 0
thread_create: 0
thread_set_state: 0
Calls made by all processes on this machine:
task_for_pid: 4085549
thread_create: 0
thread_set_state: 0
VM Region Summary:
ReadOnly portion of Libraries: Total=110.4M resident=0K(0%) swapped_out_or_unallocated=110.4M(100%)
Writable regions: Total=55.5M written=0K(0%) resident=0K(0%) swapped_out=0K(0%) unallocated=55.5M(100%)
VIRTUAL REGION
REGION TYPE SIZE COUNT (non-coalesced)
=========== ======= =======
Activity Tracing 2048K 2
Dispatch continuations 8192K 2
Kernel Alloc Once 4K 2
MALLOC 36.2M 8
MALLOC guard page 16K 4
STACK GUARD 56.0M 5
Stack 9304K 5
VM_ALLOCATE 20K 3
__DATA 3244K 58
__LINKEDIT 91.7M 12
__TEXT 18.7M 55
__UNICODE 552K 2
shared memory 12K 4
=========== ======= =======
TOTAL 225.4M 149
Can your run gdb in the command?
I wish. :-(
No working gdb, and Xcode debugger (lldb) refuses to run openssl with the arguments I'm providing. :-(
Do you build the packages with debugging?
Well, now I did. Stand by for new reports.
One good thing - RSA fixes seem to really work:
$ pkcs11-rsa-pss-sign-demo winconfig.h
openssl dgst -engine pkcs11 -keyform engine -sign "pkcs11:object=SIGN%20key;object-type=private;pin-value=123456" -sha384 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 -out winconfig.h.sig winconfig.h
initializing engine
engine "pkcs11" set.
Looking in slot -1 for key: label: SIGN key
Found 2 slots
[18446744073709551615] Virtual hotplug slot no tok
[1] Yubico Yubikey NEO OTP+U2 login (PIV_II (PIV Card Holder pin))
Found slot: Yubico Yubikey NEO OTP+U2F+CCID
Found token: PIV_II (PIV Card Holder pin)
Found 4 certificates:
1 Certificate for PIV Authentication (/CN=Mouse Mousevich)
2 Certificate for Digital Signature (/emailAddress=mouse07410@outlook.com/CN=Mouse Mousevich)
3 Certificate for Key Management (/emailAddress=mouse07410@outlook.com/CN=Mouse Mousevich)
4 Certificate for Card Authentication (/CN=Mouse Mousevich)
PKCS#11 token PIN:
Found 8 keys:
1 P PIV AUTH key
2 P SIGN key
3 P KEY MAN key
4 P CARD AUTH key
5 PIV AUTH pubkey
6 SIGN pubkey
7 KEY MAN pubkey
8 CARD AUTH pubkey
Signature for winconfig.h is stored in winconfig.h.sig
pkcs11-tool -r -y pubkey -d 02 -o /tmp/derive.52770.pubkey.02
Using slot 1 with a present token (0x1)
openssl dgst -verify /tmp/derive.52770.pubkey.02 -keyform DER -sha384 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 -signature winconfig.h.sig < winconfig.h
Verified OK
openssl dgst -engine pkcs11 -keyform engine -sha384 -verify id_02 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 -signature winconfig.h.sig winconfig.h
initializing engine
engine "pkcs11" set.
Looking in slot -1 for key: 02
Found 2 slots
[18446744073709551615] Virtual hotplug slot no tok
[1] Yubico Yubikey NEO OTP+U2 login (PIV_II (PIV Card Holder pin))
Found slot: Yubico Yubikey NEO OTP+U2F+CCID
Found token: PIV_II (PIV Card Holder pin)
Found 4 certificates:
1 Certificate for PIV Authentication (/CN=Mouse Mousevich)
2 Certificate for Digital Signature (/emailAddress=mouse07410@outlook.com/CN=Mouse Mousevich)
3 Certificate for Key Management (/emailAddress=mouse07410@outlook.com/CN=Mouse Mousevich)
4 Certificate for Card Authentication (/CN=Mouse Mousevich)
Found 4 public keys:
1 PIV AUTH pubkey
2 SIGN pubkey
3 KEY MAN pubkey
4 CARD AUTH pubkey
Verified OK
I confirm that engine_pkcs11 is currently unable to properly handle public keys. The proper fix requires fixing libp11 first, which also has an open issue for it. I have already started a major rewrite of libp11/src/p11_key.c.
@mouse07410: The ECDSA crash is a completely separate libp11 bug. Please open a new issue for libp11 and move the related comments into the newly opened issue.
Update I think I've fixed ECDSA. So now RSA (signature/verification and encryption/decryption) work fine with OpenSSL 1.0.2e, without unnecessary prompting for PIN to access public key. ECDH still needs testing.
Patches for libp11:
diff --git a/src/libp11.exports b/src/libp11.exports
index dc7b5d9..d2c19a7 100644
--- a/src/libp11.exports
+++ b/src/libp11.exports
@@ -11,6 +11,7 @@ PKCS11_is_logged_in
PKCS11_login
PKCS11_logout
PKCS11_enumerate_keys
+PKCS11_enumerate_pubkeys
PKCS11_get_key_type
PKCS11_get_key_size
PKCS11_get_key_modulus
diff --git a/src/p11_attr.c b/src/p11_attr.c
index 3f5cfcb..c618c23 100644
--- a/src/p11_attr.c
+++ b/src/p11_attr.c
@@ -31,6 +31,8 @@
#include "libp11-int.h"
+static int verbose = 0; /* print debugging output */
+
/*
* Query pkcs11 attributes
*/
diff --git a/src/p11_ec.c b/src/p11_ec.c
index e01795c..8252a0b 100644
--- a/src/p11_ec.c
+++ b/src/p11_ec.c
@@ -37,6 +37,8 @@
#include <openssl/ec.h>
#include <openssl/ecdsa.h>
+static int verbose = 0; /* printing debugging information */
+
/* To build this mode,
* OpenSSL has ECDSA_METHOD defined in internal header file ecs_locl.h
* Until this is resolved use something like:
@@ -95,7 +97,7 @@ static ECDSA_METHOD *ops = NULL;
* We need to get the EC_PARAMS and EC_POINT into both,
* as lib11 dates from RSA only where all the pub key components
* were also part of the privite key. With EC the point
- * is not in the privite key, and the params may or may not be.
+ * is not in the private key, and the params may or may not be.
*
*/
static int pkcs11_get_ec_private(PKCS11_KEY * key, EVP_PKEY * pk)
@@ -174,7 +176,7 @@ static int pkcs11_get_ec_private(PKCS11_KEY * key, EVP_PKEY * pk)
a = os->data;
o2i_ECPublicKey(&ec, &a, os->length);
}
-/* EC_KEY_print_fp(stderr, ec, 5); */
+ if (verbose) EC_KEY_print_fp(stderr, ec, 5);
}
}
}
@@ -203,8 +205,123 @@ static int pkcs11_get_ec_private(PKCS11_KEY * key, EVP_PKEY * pk)
static int pkcs11_get_ec_public(PKCS11_KEY * key, EVP_PKEY * pk)
{
+ CK_BBOOL sensitive, extractable;
+ EC_KEY * ec = NULL;
+ CK_RV ckrv;
+ int rv;
+ size_t ec_paramslen = 0;
+ CK_BYTE * ec_params = NULL;
+ size_t ec_pointlen = 0;
+ CK_BYTE * ec_point = NULL;
+ PKCS11_KEY * prkey;
+ PKCS11_KEY * pubkey;
+ ASN1_OCTET_STRING *os=NULL;
/* TBD */
- return pkcs11_get_ec_private(key, pk);
+
+ if (key->isPrivate)
+ return pkcs11_get_ec_private(key, pk);
+
+ pubkey = key;
+
+ if (pk->type == EVP_PKEY_EC) {
+ ec = EVP_PKEY_get1_EC_KEY(pk);
+ if (verbose)
+ fprintf(stderr, "pkcs11_get_ec_public(): pk->type == EVP_PKEY_EC\n");
+ } else {
+ ec = EC_KEY_new();
+ EVP_PKEY_set1_EC_KEY(pk, ec);
+ if (verbose)
+ fprintf(stderr, "pkcs11_get_ec_public(): pk->type is not EVP_PKEY_EC, called EVP_PKEY_set1_EC_KEY()\n");
+ }
+
+ if (key_getattr(pubkey, CKA_SENSITIVE, &sensitive, sizeof(sensitive))
+ || key_getattr(pubkey, CKA_EXTRACTABLE, &extractable, sizeof(extractable))) {
+ if (verbose)
+ fprintf(stderr, " ERROR! checking SENSITIVE and EXTRACTABLE attrs failed!\n");
+ EC_KEY_free(ec);
+ return -1;
+ }
+
+ if (key_getattr_var(pubkey, CKA_EC_PARAMS, NULL, &ec_paramslen) == CKR_OK &&
+ ec_paramslen > 0) {
+ ec_params = OPENSSL_malloc(ec_paramslen);
+ if (ec_params) {
+ ckrv = key_getattr_var(pubkey, CKA_EC_PARAMS, ec_params, &ec_paramslen);
+ if (ckrv == CKR_OK) {
+ const unsigned char * a = ec_params;
+ /* convert to OpenSSL parmas */
+ d2i_ECParameters(&ec, &a, ec_paramslen);
+ } else {
+ if (verbose)
+ fprintf(stderr, " key_getattr_var(...CKA_EC_PARAMS...) returned %d\n", ckrv);
+ }
+ } else {
+ if (verbose)
+ fprintf(stderr, " OPENSSL_malloc(%1d) failed!\n", ec_paramslen);
+ }
+ } else {
+ if (verbose)
+ fprintf(stderr, " ERROR! Could not retrieve ec_paramslen\n");
+ }
+
+ if (verbose)
+ fprintf(stderr, " about to call key_getattr_var(pubkey, CKA_EC_POINT, NULL, &ec_pointlen)\n");
+
+ ckrv = key_getattr_var(pubkey, CKA_EC_POINT, NULL, &ec_pointlen);
+ if (ckrv == CKR_OK && ec_pointlen > 0) {
+ if (verbose)
+ fprintf(stderr, " ckrv=%d ec_pointlen=%d\n", ckrv, ec_pointlen);
+ ec_point = OPENSSL_malloc(ec_pointlen);
+ if (ec_point) {
+ ckrv = key_getattr_var(pubkey, CKA_EC_POINT, ec_point, &ec_pointlen);
+ if (verbose)
+ fprintf(stderr, "key_getattr_var(pubkey,CKA_EC_POINT, ec_point,...) == %d\n", ckrv);
+
+ if (ckrv == CKR_OK) {
+ if (verbose)
+ fprintf(stderr, "key_getattr_var() returned CKR_OK\n");
+
+ /* PKCS#11 returns ASN1 octstring*/
+ const unsigned char * a;
+ /* we have asn1 octet string, need to strip off 04 len */
+
+ a = ec_point;
+ os = d2i_ASN1_OCTET_STRING(NULL, &a, ec_pointlen);
+ if (os) {
+ a = os->data;
+ o2i_ECPublicKey(&ec, &a, os->length);
+ }
+ if (verbose)
+ EC_KEY_print_fp(stderr, ec, 5);
+ }
+ }
+ } else {
+ if (verbose)
+ fprintf(" ERROR: ckrv=%d ec_pointlen=%d\n", ckrv, ec_pointlen);
+ }
+
+ if (os)
+ M_ASN1_OCTET_STRING_free(os);
+ if (ec_point)
+ OPENSSL_free(ec_point);
+ if (ec_params)
+ OPENSSL_free(ec_params);
+
+ if (verbose)
+ fprintf(stderr, "pkcs11_get_ec_public(): freed os, ec_point, ec_params\n");
+
+ if (sensitive || !extractable) {
+ ECDSA_set_ex_data(ec, 0, key);
+ EC_KEY_free(ec); /* drops our reference to it. */
+ return 0;
+ }
+
+ if (ec)
+ EC_KEY_free(ec);
+ if (verbose)
+ fprintf(stderr, "pkcs11_get_ec_public(): about to return -1\n");
+ return -1;
+
}
/* TODO Looks like this is never called */
diff --git a/src/p11_key.c b/src/p11_key.c
index dba1480..facf16d 100644
--- a/src/p11_key.c
+++ b/src/p11_key.c
@@ -24,6 +24,8 @@
#define strncasecmp strnicmp
#endif
+static int verbose = 0;
+
static int pkcs11_find_keys(PKCS11_TOKEN *, unsigned int);
static int pkcs11_next_key(PKCS11_CTX * ctx, PKCS11_TOKEN * token,
CK_SESSION_HANDLE session, CK_OBJECT_CLASS type);
@@ -63,10 +65,30 @@ PKCS11_enumerate_keys(PKCS11_TOKEN * token, PKCS11_KEY ** keyp, unsigned int *co
}
}
*keyp = priv->keys;
- *countp = priv->nprkeys;
+ // *countp = priv->nprkeys;
+ *countp = priv->nkeys;
return 0;
}
+int
+PKCS11_enumerate_pubkeys(PKCS11_TOKEN * token, PKCS11_KEY ** keyp, unsigned int *countp)
+{
+ PKCS11_TOKEN_private *priv = PRIVTOKEN(token);
+
+ priv->nkeys = 0;
+
+ if (pkcs11_find_keys(token, CKO_PUBLIC_KEY)) {
+ pkcs11_destroy_keys(token);
+ if (verbose) {
+ fprintf(stderr, "pkcs11_find_keys(CKO_PUBLIC_KEYS) returned error\n");
+ }
+ return -1;
+ }
+ *keyp = priv->keys;
+ *countp = priv->nkeys;
+ return 0;
+}
+
/*
* Find key matching a certificate
*/
Patches for engine_pkcs11:
diff --git a/src/engine_pkcs11.c b/src/engine_pkcs11.c
index 5f5e9c6..b517364 100644
--- a/src/engine_pkcs11.c
+++ b/src/engine_pkcs11.c
@@ -811,6 +811,11 @@ static EVP_PKEY *pkcs11_load_key(ENGINE * e, const char *s_slot_key_id,
size_t tmp_pin_len = sizeof(tmp_pin);
char flags[64];
+ if (verbose)
+ fprintf(stderr, "pkcs11_load_key(...,\"%s\",...,...,%s)\n",
+ s_slot_key_id,
+ (char *)(isPrivate?"Private":"Public")
+ );
if (s_slot_key_id && *s_slot_key_id) {
if (!strncmp(s_slot_key_id, "pkcs11:", 7)) {
n = parse_pkcs11_uri(s_slot_key_id, &match_tok,
@@ -941,10 +946,10 @@ static EVP_PKEY *pkcs11_load_key(ENGINE * e, const char *s_slot_key_id,
return NULL;
}
/* Removed for interop with some other pkcs11 libs. */
-#if 0
+#if 1
if (!tok->initialized) {
fprintf(stderr, "Found uninitialized token; \n");
- return NULL;
+ //return NULL;
}
#endif
if (isPrivate && !tok->userPinSet && !tok->readOnly) {
@@ -980,23 +985,43 @@ static EVP_PKEY *pkcs11_load_key(ENGINE * e, const char *s_slot_key_id,
}
}
- /* Perform login to the token if required */
- if (!pkcs11_login(slot, tok, ui_method, callback_data)) {
- return NULL;
- }
-
- /* Make sure there is at least one private key on the token */
- if (PKCS11_enumerate_keys(tok, &keys, &key_count)) {
- fail("unable to enumerate keys\n");
- }
- if (key_count == 0) {
- fail("No keys found.\n");
- }
- if (verbose) {
- fprintf(stderr, "Found %u key%s:\n", key_count,
- (key_count <= 1) ? "" : "s");
+ if (isPrivate) {
+
+ /* Perform login to the token if required */
+ if (!pkcs11_login(slot, tok, ui_method, callback_data)) {
+ fprintf(stderr, "login to token failed, returning NULL...\n");
+ return NULL;
+ }
+
+ /* Make sure there is at least one private key on the token */
+ if (PKCS11_enumerate_keys(tok, &keys, &key_count)) {
+ fail("unable to enumerate keys\n");
+ }
+ if (key_count == 0) {
+ fail("No keys found.\n");
+ }
+
+ if (verbose) {
+ fprintf(stderr, "Found %u key%s:\n", key_count,
+ (key_count <= 1) ? "" : "s");
+ }
+ } else {
+
+ /* Make sure there is at least one public key on the token */
+ if (PKCS11_enumerate_pubkeys(tok, &keys, &key_count)) {
+ fail("unable to enumerate public keys\n");
+ }
+ if (key_count == 0) {
+ fail("No public keys found.\n");
+ }
+
+ if (verbose) {
+ fprintf(stderr, "Found %u public key%s:\n", key_count,
+ (key_count <= 1) ? "" : "s");
+ }
}
+
if (s_slot_key_id && *s_slot_key_id && (key_id_len != 0 || key_label != NULL)) {
for (n = 0; n < key_count; n++) {
PKCS11_KEY *k = keys + n;
@@ -1031,7 +1056,7 @@ static EVP_PKEY *pkcs11_load_key(ENGINE * e, const char *s_slot_key_id,
} else {
/*pk = PKCS11_get_public_key(&keys[0]);
need a get_public_key? */
- pk = PKCS11_get_private_key(selected_key);
+ pk = PKCS11_get_public_key(selected_key);
}
if (key_label != NULL)
free(key_label);
Also, in order for engine_pkcs11
to work correctly (at least on my Mac) it is necessary to edit config.h
(I did it manually, would be nice if configuration could do it for me) and change the default PKCS11 module to OpenSC opensc-pkcs11.so
. Here's what it should look like on Mac:
/* p11-kit proxy */
#define DEFAULT_PKCS11_MODULE "/Library/OpenSC/lib/opensc-pkcs11.so"
The above works, and despite having GnuTLS and libp11 installed, my system does not have p11-kit-proxy anywhere.
Demo of the results:
$ pkcs11-ecdsa-demo xxtea.py.enc
Using reader with a card: Yubico Yubikey 4 OTP+U2F+CCID
read EC key
openssl dgst -sha384 -binary -out /tmp/derive.60527.sha384 xxtea.py.enc
pkcs11-tool --sign -f 'openssl' -m ECDSA -d 02 -i /tmp/derive.60527.sha384 -o /tmp/xxtea.py.enc.sig
Using slot 1 with a present token (0x1)
Logging in to "PIV_II (PIV Card Holder pin)".
Please enter User PIN:
Using signature algorithm ECDSA
Signature for xxtea.py.enc is stored in /tmp/xxtea.py.enc.sig
pkcs11-tool -r -y pubkey -d 02 -o /tmp/derive.60527.02
Using slot 1 with a present token (0x1)
openssl dgst -verify /tmp/derive.60527.02 -keyform DER -sha384 -signature /tmp/xxtea.py.enc.sig < xxtea.py.enc
Verified OK
openssl dgst -engine pkcs11 -keyform engine -sha384 -verify "pkcs11:object=SIGN%20pubkey;object-type=public" -signature /tmp/xxtea.py.enc.sig xxtea.py.enc
engine "pkcs11" set.
Verified OK
$ pkcs11-rsa-pss-sign-demo xxtea.py.enc
openssl dgst -engine pkcs11 -keyform engine -sign "pkcs11:object=SIGN%20key;object-type=private;pin-value=123456" -sha384 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 -out xxtea.py.enc.sig xxtea.py.enc
engine "pkcs11" set.
PKCS#11 token PIN:
Signature for xxtea.py.enc is stored in xxtea.py.enc.sig
pkcs11-tool -r -y pubkey -d 02 -o /tmp/derive.60552.pubkey.02
Using slot 1 with a present token (0x1)
openssl dgst -verify /tmp/derive.60552.pubkey.02 -keyform DER -sha384 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 -signature xxtea.py.enc.sig < xxtea.py.enc
Verified OK
openssl dgst -engine pkcs11 -keyform engine -sha384 -verify id_02 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 -signature xxtea.py.enc.sig xxtea.py.enc
engine "pkcs11" set.
Verified OK
@mtrojnar I concur that a rewrite wouldn't hurt, but in the meanwhile the patches I offered seem to do the job sufficiently well to use them. As I said, they work fine for RSA (all modes) and EC (tested ECDSA signature, and partially ECDH). Since it's unclear how long it would take to rewrite this fairly large piece of code (and whether any new problems would be introduced in the process that could delay deployment), please consider incorporating these patches, at least for the time being.
I suspect that ec was null.
It was never a dummy routine.
The private key may not have the namedCurve. The code was meant to
find the namedCurve from the public key.
There are terminology differences between OPenSSL and PKCS#11 as to
what is in the private key, or in the public key. With RSA with no
parameters it was easy. With EC the namedCurve
(or ecParameters) are needed to determine properties of the private
key.
On 12/29/2015 4:08 PM, Mouse wrote:
Here's the code of pkcs11_get_ec_public(), as it
was a dummy routine calling pkcs11_get_ec_private()
before:
if (verbose)
EC_KEY_print_fp(stderr, ec, 5);
}
}
}
if (os)
M_ASN1_OCTET_STRING_free(os);
if (ec_point)
OPENSSL_free(ec_point);
if (ec_params)
OPENSSL_free(ec_params);
if (sensitive || !extractable) {
ECDSA_set_ex_data(ec, 0, key);
EC_KEY_free(ec); /* drops our reference to it. */
return 0;
}
if (ec)
EC_KEY_free(ec);
return -1;
}
—
Reply to this email directly or view
it on GitHub.
--
Douglas E. Engert DEEngert@gmail.com
pkcs11_get_ec_private should have been renamed pkcs11_get_ec_key
log ago as it is called with the PKCS11_KEY which has
a flag to say if it is for the public or private. the
key->isPrivate
92 /*
93 * Get EC key material and stach pointer in ex_data
94 * Note we get called twice, once for private key, and once
for public
95 * We need to get the EC_PARAMS and EC_POINT into both,
96 * as lib11 dates from RSA only where all the pub key
components
97 * were also part of the privite key. With EC the point
98 * is not in the privite key, and the params may or may not
be.
99 *
100 */
On 12/29/2015 4:39 PM, Mouse wrote:
Changing pkcs11_get_ec_public() to call pkcs11_get_ec_private()
like before, gets signature creation working:
$ openssl dgst -engine pkcs11 -keyform engine -sha384 -sign "pkcs11:object=SIGN%20key;object-type=private" -out t.sig stamp-h1
initializing engine engine "pkcs11" set. Looking in slot -1 for key: label: SIGN key Found 2 slots [18446744073709551615] Virtual hotplug slot no tok [1] Yubico Yubikey 4 OTP+U2F+ login (PIV_II (PIV Card Holder pin)) Found slot: Yubico Yubikey 4 OTP+U2F+CCID Found token: PIV_II (PIV Card Holder pin) Found 4 certificates: 1 Certificate for PIV Authentication (/CN=Uri the Great) 2 Certificate for Digital Signature (/CN=Uri the Great) 3 Certificate for Key Management (/CN=Uri the Great) 4 Certificate for Card Authentication (/CN=Uri the Great) PKCS#11 token PIN: Found 8 keys: 1 P PIV AUTH key 2 P SIGN key 3 P KEY MAN key 4 P CARD AUTH key 5 PIV AUTH pubkey 6 SIGN pubkey 7 KEY MAN pubkey 8 CARD AUTH pubkey Private-Key: (384 bit) pub: 04:32:3d:ac:5d:34:44:9a:c1:70:73:d5:ee:de:c1: 53:26:48:da:7e:19:04:c7:70:3a:a4:38:4b:fd:60: d4:ca:ab:4d:f5:0b:cf:d3:d4:2d:d4:d0:da:15:97: 32:c1:2b:d6:01:64:70:05:da:35:f5:cf:16:c4:a3: 67:4a:59:15:4c:a2:e6:6d:8e:e8:1e:11:5c:4a:9b: e8:9c:21:fc:19:b2:9f:0f:99:1b:f0:82:39:d0:08: 15:63:44:35:09:08:f9 ASN1 OID: secp384r1 NIST CURVE: P-384 Private-Key: (384 bit) pub: 04:32:3d:ac:5d:34:44:9a:c1:70:73:d5:ee:de:c1: 53:26:48:da:7e:19:04:c7:70:3a:a4:38:4b:fd:60: d4:ca:ab:4d:f5:0b:cf:d3:d4:2d:d4:d0:da:15:97: 32:c1:2b:d6:01:64:70:05:da:35:f5:cf:16:c4:a3: 67:4a:59:15:4c:a2:e6:6d:8e:e8:1e:11:5c:4a:9b: e8:9c:21:fc:19:b2:9f:0f:99:1b:f0:82:39:d0:08: 15:63:44:35:09:08:f9 ASN1 OID: secp384r1 NIST CURVE: P-384 $ ll t.sig -rw-r--r-- 1 uri staff 102 Dec 29 17:38 t.sig $ dumpasn1 t.sig 0 100: SEQUENCE { 2 48: INTEGER : 09 33 31 99 B7 C6 C6 9D AE 69 94 0A 35 CB 38 7F : 69 00 4D 21 39 7C 7B 40 07 5F DC 45 DF AC EA 80 : AA F3 7E 02 C4 80 7B 67 16 81 5A CF C1 C1 C1 DC 52 48: INTEGER : 36 92 EE 2B 08 E5 0F EB CE 90 6B 01 AE 45 47 70 : C5 9B 25 B3 37 97 BE 6A F7 1F F0 F9 9B F1 65 DF : 7D E7 48 8E D0 11 47 3F E5 05 6F 22 AE 4B 8D 87 : }
0 warnings, 0 errors. $
But attempts to verify an ECDSA signature result in:
$ openssl dgst -d -engine pkcs11 -keyform engine -sha384 -verify "pkcs11:object=SIGN%20pubkey;object-type=public" -signature t.sig winconfig.h
initializing engine engine "pkcs11" set. Looking in slot -1 for key: label: SIGN pubkey Found 2 slots [18446744073709551615] Virtual hotplug slot no tok [1] Yubico Yubikey 4 OTP+U2F+ login (PIV_II (PIV Card Holder pin)) Found slot: Yubico Yubikey 4 OTP+U2F+CCID Found token: PIV_II (PIV Card Holder pin) Found 4 certificates: 1 Certificate for PIV Authentication (/CN=Uri the Great) 2 Certificate for Digital Signature (/CN=Uri the Great) 3 Certificate for Key Management (/CN=Uri the Great) 4 Certificate for Card Authentication (/CN=Uri the Great) Found 4 public keys: 1 PIV AUTH pubkey 2 SIGN pubkey 3 KEY MAN pubkey 4 CARD AUTH pubkey Out of memory 140735231131728:error:10098043:elliptic curve routines:o2i_ECPublicKey:passed a null parameter:ec_asn1.c:1271: 140735231131728:error:100DD043:elliptic curve routines:DO_EC_KEY_PRINT:passed a null parameter:ec_ameth.c:489: BIO[0x7ff393c01d80]: Free - FILE pointer
—
Reply to this email directly or view
it on GitHub.
--
Douglas E. Engert DEEngert@gmail.com
Submitted a PR that fixes all of the above: https://github.com/OpenSC/engine_pkcs11/pull/34
Hope it would be merged.
File
src/engine_pkcs11.c
, around line 989:Call to
PKCS11_enumerate_keys()
returns only the private keys. I think it should include public keys as well.If this function/method is unable to do so, what are the alternatives?