Closed jmastr closed 4 years ago
Why do you think it hangs, are you sure to present the correct certificate to the website? Does client authentication work on Firefox?
Does client authentication work on Firefox?
Unfortunately I cannot test that, because I can only access the page via Chrome.
Why do you think it hangs, are you sure to present the correct certificate to the website?
Maybe hangs is not wrong wording. The log output just stops, where in rc3 I could a call to sc_pkcs15_compute_signature
. I compared the serial numbers of the certificates. It is the same in both cases.
Could keychain and token interfere with each other?
OpenSC-0.20.0-rc3:
% system_profiler SPSmartCardsDataType
SmartCards:
Readers:
#01: Identiv SCR3500 C Contact Reader (ATR:{length = 24, bytes = 0x3bbfb6008131fe5d00640428030231c073f701d000900067})
Reader Drivers:
#01: org.debian.alioth.pcsclite.smartcardccid:1.4.31 (/usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle)
#02: com.scmmicro.drivers.scmccid:(null) (/usr/local/libexec/SmartCardServices/drivers/scmccid.bundle)
Tokend Drivers:
SmartCard Drivers:
#01: org.opensc-project.mac.opensctoken.OpenSCTokenApp.OpenSCToken:1.1.1 (/Applications/OpenSCTokenApp.app/Contents/PlugIns/OpenSCToken.appex)
#02: com.apple.CryptoTokenKit.pivtoken:1.0(disabled) (/System/Library/Frameworks/CryptoTokenKit.framework/PlugIns/pivtoken.appex)
Available SmartCards (keychain):
com.apple.setoken:
com.apple.setoken:aks:
org.opensc-project.mac.opensctoken.OpenSCTokenApp.OpenSCToken:8949017360005891279:
#01: Kind: private RSA 2048-bit, Certificate: {length = 20, bytes = 0x743f677bb2476541d4fae546bab5e01d161f0da1}, Usage: Sign Decrypt Unwrap
Valid from: 2018-05-02 06:55:21 +0000 to: 2021-05-01 06:55:21 +0000, SSL trust: YES, X509 trust: YES
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
#02: Kind: private RSA 2048-bit, Certificate: {length = 20, bytes = 0x743f677bb2476541d4fae546bab5e01d161f0da1}, Usage: Sign Decrypt Unwrap
Valid from: 2018-05-02 06:55:21 +0000 to: 2021-05-01 06:55:21 +0000, SSL trust: YES, X509 trust: YES
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
Available SmartCards (token):
com.apple.setoken:
com.apple.setoken:aks:
org.opensc-project.mac.opensctoken.OpenSCTokenApp.OpenSCToken:8949017360005891279:
#01: Kind: private RSA 2048-bit, Certificate: no, Usage: Sign Decrypt Unwrap
Valid from: N/A to: N/A, SSL trust: N/A, X509 trust: N/A
#02: Certificate {length = 20, bytes = 0x849f4a16434720fb25500ac0597a1954d38f78e9}
OpenSC-0.20.0-rc4:
% system_profiler SPSmartCardsDataType
SmartCards:
Readers:
#01: Identiv SCR3500 C Contact Reader (ATR:{length = 24, bytes = 0x3bbfb6008131fe5d00640428030231c073f701d000900067})
Reader Drivers:
#01: org.debian.alioth.pcsclite.smartcardccid:1.4.31 (/usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle)
#02: com.scmmicro.drivers.scmccid:(null) (/usr/local/libexec/SmartCardServices/drivers/scmccid.bundle)
Tokend Drivers:
SmartCard Drivers:
#01: org.opensc-project.mac.opensctoken.OpenSCTokenApp.OpenSCToken:1.1.1 (/Applications/OpenSCTokenApp.app/Contents/PlugIns/OpenSCToken.appex)
#02: com.apple.CryptoTokenKit.pivtoken:1.0(disabled) (/System/Library/Frameworks/CryptoTokenKit.framework/PlugIns/pivtoken.appex)
Available SmartCards (keychain):
com.apple.setoken:
com.apple.setoken:aks:
org.opensc-project.mac.opensctoken.OpenSCTokenApp.OpenSCToken:8949017360005891279:
#01: Kind: private RSA 2048-bit, Certificate: {length = 20, bytes = 0x743f677bb2476541d4fae546bab5e01d161f0da1}, Usage: Sign Decrypt Unwrap
Valid from: 2018-05-02 06:55:21 +0000 to: 2021-05-01 06:55:21 +0000, SSL trust: YES, X509 trust: YES
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
#02: Kind: private RSA 2048-bit, Certificate: {length = 20, bytes = 0x849f4a16434720fb25500ac0597a1954d38f78e9}, Usage: Sign Decrypt Unwrap
Valid from: 2018-05-02 06:55:24 +0000 to: 2021-05-01 06:55:24 +0000, SSL trust: NO, X509 trust: YES
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
Available SmartCards (token):
com.apple.setoken:
com.apple.setoken:aks:
org.opensc-project.mac.opensctoken.OpenSCTokenApp.OpenSCToken:8949017360005891279:
#01: Kind: private RSA 2048-bit, Certificate: {length = 20, bytes = 0x743f677bb2476541d4fae546bab5e01d161f0da1}, Usage: Sign Decrypt Unwrap
Valid from: 2018-05-02 06:55:21 +0000 to: 2021-05-01 06:55:21 +0000, SSL trust: YES, X509 trust: YES
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
#02: Kind: private RSA 2048-bit, Certificate: {length = 20, bytes = 0x849f4a16434720fb25500ac0597a1954d38f78e9}, Usage: Sign Decrypt Unwrap
Valid from: 2018-05-02 06:55:24 +0000 to: 2021-05-01 06:55:24 +0000, SSL trust: NO, X509 trust: YES
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
I am goind to upgrade from 10.15.1
to 10.15.2
. Maybe that helps... I keep you posted.
@frankmorgner So I did a lot of digging yesterday and I made it work! :) However before commiting a patch I would like to discuss some things.
First of all, this is the code line my card cannot pass: https://github.com/frankmorgner/OpenSCToken/blob/d508acf2924c0e216b7c9ffeb40a0667494c14e6/OpenSCToken/TokenSession.m#L202-L203
Adding some debug log it was shown that algorithmToFlags(TKTokenKeyAlgorithm * algorithm)
would return SC_ALGORITHM_RSA_RAW
or (unsigned int) -1
(I was not able to find which alogrithm the OS/Browser request) for minimum_flags
.
For SC_ALGORITHM_RSA_RAW
: it was removed in https://github.com/OpenSC/OpenSC/commit/bee5c6d6396b07543e3c24bab2fad275ccf9de91. The only signature scheme left is SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE
. Can we be sure that my card does not support SC_ALGORITHM_RSA_RAW
?
Last but not least in my case it wants to calculate a signature with datalen = 256
, so it cannot pass this line: https://github.com/OpenSC/OpenSC/blob/ee78b0b80514460936c585c3ff5fc477338ae371/src/libopensc/card-tcos.c#L554. Replacing:
- if (datalen > 255) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS);
+ if (datalen > 256) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS);
works. Could this be an "off-by-one" error?
Thank you for your help!
Maybe, @Jakuje, can look at the TCOS properties...
Here is a list of Apple's security mechanisms: https://developer.apple.com/documentation/security/seckeyalgorithm?language=objc In OpenSCToken, I don't check for kSecKeyAlgorithmRSASignatureDigestPKCS1v15Raw
, which could maybe be translated to SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE
, which would be possible with the current TCOS flags. Apple's flags, however, aren't specified very well, so I'm not sure.
Just to be exact, what would be the exact patch to make client authentication work for you?
Possible solution 1 (known working):
diff --git a/src/libopensc/card-tcos.c b/src/libopensc/card-tcos.c
index c2476a37..82533fbf 100644
--- a/src/libopensc/card-tcos.c
+++ b/src/libopensc/card-tcos.c
@@ -95,9 +95,7 @@ static int tcos_init(sc_card_t *card)
card->drv_data = (void *)data;
card->cla = 0x00;
- if (card->type != SC_CARD_TYPE_TCOS_V3) {
- flags |= SC_ALGORITHM_RSA_RAW;
- }
+ flags = SC_ALGORITHM_RSA_RAW;
flags |= SC_ALGORITHM_RSA_PAD_PKCS1;
flags |= SC_ALGORITHM_RSA_HASH_NONE;
@@ -551,7 +549,7 @@ static int tcos_compute_signature(sc_card_t *card, const u8 * data, size_t datal
assert(card != NULL && data != NULL && out != NULL);
tcos3=(card->type==SC_CARD_TYPE_TCOS_V3);
- if (datalen > 255) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS);
+ if (datalen > 256) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS);
if(((tcos_data *)card->drv_data)->next_sign){
if(datalen>48){
Possible solution 2 (untested):
diff --git a/OpenSCToken/TokenSession.m b/OpenSCToken/TokenSession.m
index 442011c..a4af6ab 100644
--- a/OpenSCToken/TokenSession.m
+++ b/OpenSCToken/TokenSession.m
@@ -34,6 +34,8 @@ static unsigned int algorithmToFlags(TKTokenKeyAlgorithm * algorithm)
if ([algorithm isAlgorithm:kSecKeyAlgorithmRSAEncryptionRaw]
|| [algorithm isAlgorithm:kSecKeyAlgorithmRSASignatureRaw])
return SC_ALGORITHM_RSA_RAW;
+ if ([algorithm isAlgorithm:kSecKeyAlgorithmRSASignatureDigestPKCS1v15Raw])
+ return SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE;
if ([algorithm isAlgorithm:kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1])
return SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA1;
if ([algorithm isAlgorithm:kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA224])
diff --git a/src/libopensc/card-tcos.c b/src/libopensc/card-tcos.c
index c2476a37..82533fbf 100644
--- a/src/libopensc/card-tcos.c
+++ b/src/libopensc/card-tcos.c
@@ -551,7 +549,7 @@ static int tcos_compute_signature(sc_card_t *card, const u8 * data, size_t datal
assert(card != NULL && data != NULL && out != NULL);
tcos3=(card->type==SC_CARD_TYPE_TCOS_V3);
- if (datalen > 255) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS);
+ if (datalen > 256) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS);
if(((tcos_data *)card->drv_data)->next_sign){
if(datalen>48){
With rc3, the card is still using RAW signature operation emulated with TCOS decryption operation, which is not completely fine. This gets selected by next_sign
switch for some key ids. Indeed, in that case you need to bump the 255 to 256 to fit the whole padded input for your key size (and bump it again when the supported key size will increase).
From the input data
in tcos_compute_signature()
, we could see whether it is PKCS1 padded data from browser (does start with 0x00 0x01
or 0x00 0x02
) or RSA-PSS (does it end with 0xbc
?), but if you are using something reasonably new, negotiating TLS 1.3 it will already have to be RSA-PSS (not sure how this gets supported through the OSX stack).
In any way, misusing this works only as long as these padding checks will not be performed by card.
@Jakuje I kind of understand what your are writing. I put in all the debug output I could and here is what's requested by the OS (for pairing):
kSecKeyAlgorithmRSAEncryptionOAEPSHA256
kSecKeyAlgorithmRSAEncryptionOAEPSHA256AESGCM
kSecKeyAlgorithmRSAEncryptionRaw
and by the Browser (for signing):
kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1
kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256
kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384
kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512
kSecKeyAlgorithmRSASignatureDigestPSSSHA256
kSecKeyAlgorithmRSASignatureDigestPSSSHA384
kSecKeyAlgorithmRSASignatureDigestPSSSHA512
kSecKeyAlgorithmRSASignatureRaw
It always comes back to kSecKeyAlgorithmRSA{Encryption|Signature}Raw
:(
Yes. The OAEP is not supported natively by your driver and then it falls back to raw operation while doing the OAEP internally. Not sure what is the pairing for though.
But the kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1
(RSA-PKCS1.5 with SHA1) should work just fine as it should be advertised by the OpenSC known algorithm (If I remember well from the previous logs). Wondering why it was not selected/used in your case. This does not look like TLS 1.3 mechanisms.
pairing
One can pair his/her MacOS user with the smartcard or what do you mean?
kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1
card-tcos.c only advertises: SC_ALGORITHM_RSA_PAD_PKCS1 and SC_ALGORITHM_RSA_HASH_NONE, no? So SHA1 is not supported by the card? Sorry for my lack of knowledge...
In https://github.com/OpenSC/OpenSC/issues/1869#issuecomment-561180334 you reported that the SHA1-RSA-PKCS
worked with the testing key 1. And this mechanism should correspond to the kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1
, if I am right.
That is true. However in: https://github.com/OpenSC/OpenSC/blob/ee78b0b80514460936c585c3ff5fc477338ae371/src/libopensc/card-tcos.c#L98-L102 those SC_ALGORITHMRSA* flags are set and checked against: https://github.com/frankmorgner/OpenSCToken/blob/84e0052e15b63fe87841187a413cdc42c0da6bb1/OpenSCToken/TokenSession.m#L32-L63.
Meaning to support SHA1 I would need to add SC_ALGORITHM_RSA_HASH_SHA1 in card-tcos.c. Would that be okay? I am not sure where pkcs11-tool gets that information from.
The important question is whether it will work.
See the commend in https://github.com/OpenSC/OpenSC/blob/master/src/libopensc/opensc.h#L126 -- for RSA PKCS1.5 the NONE value means that the hashing is not done by the card. But it does not mean that the hashing can not be done by the OpenSC.
With:
diff --git a/src/libopensc/card-tcos.c b/src/libopensc/card-tcos.c
index c2476a37..ea26d99b 100644
--- a/src/libopensc/card-tcos.c
+++ b/src/libopensc/card-tcos.c
@@ -100,6 +100,9 @@ static int tcos_init(sc_card_t *card)
}
flags |= SC_ALGORITHM_RSA_PAD_PKCS1;
flags |= SC_ALGORITHM_RSA_HASH_NONE;
+ if (card->type == SC_CARD_TYPE_TCOS_V3) {
+ flags |= SC_ALGORITHM_RSA_HASH_SHA1;
+ }
_sc_card_add_rsa_alg(card, 512, flags, 0);
_sc_card_add_rsa_alg(card, 768, flags, 0);
I receive tcos_compute_signature: returning with: -1211 (Security status not satisfied)
Log: https://gist.github.com/jmastr/0076aba4fc6392a8b7c7e53652501ab0
I don't know whether we can solve this issue in a satisfactory manner...
The thing is that SC_ALGORITHM_RSA_RAW
for TCOS was introduced back in 2002 by Werner Koch with https://github.com/OpenSC/OpenSC/commit/d9a788350ddc30d620cb5647ccc58bca7ece951d and afaik it worked for people.
we really need more documentation and an active developer
I asked again for more documentation.
Can we revert https://github.com/OpenSC/OpenSC/commit/992ed48d8960e45e26b8384e6e376e754544eed0 and put a comment to it?
No problem. Go ahead.
OK, @jmastr please make a PR with the suggested changes. Please also run pkcs11-tool --test
with it.
@frankmorgner Thank you for uploading the
dmg
file for OpenSC-0.20.0-rc4! With the new release candidate I encounter a strange behaviour:signData
(which itself callssc_pkcs15_compute_signature
) from TokenSessions.m is not called, when I try to log in into a webpage via certificate.On the same machine downgrading from OpenSC-0.20.0-rc4 to OpenSC-0.20.0-rc3 gives me the expected log output (but fails to sign the request due to another issue with TCOS, which was fixed in OpenSC-0.20.0-rc4).
Here is some logs. First OpenSC-0.20.0-rc3:
Here from OpenSC-0.20.0-rc4, where is just hangs:
The strange thing is, even building OpenSC-0.20.0-rc3 on my local machine and trying different commits from OpenSCToken yield to the same result. Have there been any updates to the build environment? How does
signData
get called?Thank you for your help!