PeculiarVentures / fortify

Fortify enables web applications to use smart cards, local certificate stores and do certificate enrollment. This is the desktop application repository.
https://fortifyapp.com
Other
114 stars 33 forks source link

Fortify is unable to communicate with smartcard while signing operation. #576

Open pmhatre-swi opened 1 month ago

pmhatre-swi commented 1 month ago

While signing the operations from Airvantage signing portal, We observe an exception "Fortify is unable to communicate with smartcard." () We have loaded client certificate in slot 9A (Authentication slot) and intermediate certificate in slot 9d (Key Management slot) of the Yubikey. We have also tried with slot 82-95 for uploading certificate chain (Intermediate certificate / Root certificate) on Yubikey.

We observe the issue when certificate chain (Root - Intermediate - Client) is based on OpenSSL ECDSA algorithm or Microsoft CA rsassa-pss algorithm.

Attached Fortify logs for the reference. Fortify_logs.txt

Details are provided below: OS -Windows 11 Browser - Firefox 125.0.3 Yubikey - YubiKey 5 NFC (FW: 5.4.3)

image

pmhatre-swi commented 1 month ago

Error with Microsoft CA rsassa-pss algorithm.

image

Error with OpenSSL ECDSA algorithm.

CKR data invalid error with openssl intermediate

pmhatre-swi commented 1 month ago

Currently, we are not seeing issue ("error":"CKR_DATA_INVALID") with OpenSSL ECDSA algorithm. (maybe intermittent issue) but issue is getting reproduced consistently with Microsoft CA rsassa-pss algorithm.

microshine commented 1 month ago

@pmhatre-swi I will check this and provide a report as soon as possible.

microshine commented 1 month ago

Thanks to today's meeting, I was able to reproduce the error CryptoServerError: Unrecognized name. The issue lies in the fact that the current version of Fortify has an outdated implementation for building certificate chains. The main problem is that when constructing the chain from the certificates obtained from the token, Fortify uses the cryptography of the token itself for certificate verification, which leads to the error. This issue particularly arises when using the RSA-PSS mechanism.

The new version of Fortify, v2, employs a different approach that will resolve this error.

Additionally, you can build the chain on the client side using the @peculiar/x509 module. Here's an example: https://peculiarventures.github.io/fortify-examples/example6.html. There was also an issue with the RSA-PSS mechanism in this module. I will publish the fixes to @peculiar/x509 shortly and will notify you once they are available.

microshine commented 1 month ago

I have published the updated version of @peculiar/x509 and updated the script on https://peculiarventures.github.io/fortify-examples/example6.html. The chain is now built using the RSA-PSS algorithm.

pmhatre-swi commented 1 month ago

I checked the chain created using: https://peculiarventures.github.io/fortify-examples/example6.html I still don't see the entire chain is fetched from the Yubikey.

peculiar lib RSASSA-PSS

I have uploaded Client certificate in slot 9a (Authentication) and Intermediate certificate in slot 9d (Key Management) I have also tried with certificates uploaded to hidden slots 82-83

microshine commented 1 month ago

I have just updated and published new examples. The chain builder example now logs information about all received certificates from the token into the developer console. Please try it once more and check that list. Additionally, please double-check that Fortify uses the ykcs11 library and ensure that the list contains all certificates from all Yubico slots. If you find all required certificates in the log but it still doesn't build a correct chain, please share your certificates with me. I will attempt to build the chain locally and identify why the x509 module isn't constructing the chain correctly.

image
pmhatre-swi commented 1 month ago

I checked with the new example. I observed that only client certificate is fetched from Yubikey even though all certificates are uploaded to Yubikey. Web developers console shows only client certificate. peculiar lib RSASSA-PSS 2

Fortify logs shows that ykcs11 library is used. {"level":"info","library":"C:\WINDOWS\System32\libykcs11-1.dll","message":"Loading PKCS#11 library","source":"provider","timestamp":"2024-05-24T09:43:54.876Z"}

attaching Developer console logs, Fortify Logs, Yubikey Slot Details and Certificate chain. (Root certificate, Intermediate certificate and Client certificate) Developer tools console logs.txt Fortify Logs.txt RSASSA-PSS Certificate chain.zip Yubikey Slot certificate details.txt

microshine commented 1 month ago

Please update your ~/.fortify/card.json file and change the path for libykcs11-1.dll. It looks like this is a previous version of Yubico PKCS#11 and it doesn't support all slots. There should be the latest version. Please switch to it and don't forget to restart Fortify.

In the C:\WINDOWS\System32\ folder or the Yubico PIV Tools installation directory, you should find additional libraries with other versions. As an example, on macOS, you can list the versions as follows:

% ls /usr/local/lib/libykcs11*
/usr/local/lib/libykcs11.2.5.1.dylib  /usr/local/lib/libykcs11.a
/usr/local/lib/libykcs11.2.dylib      /usr/local/lib/libykcs11.dylib
pmhatre-swi commented 1 month ago

I updated my ~/.fortify/card.json file. and made changes to library path to point to the Yubico PIV Tools lib. "windows": "C:\Program Files\Yubico\Yubico PIV Tool\bin\libykcs11.dll"

I also updated my Yubikey Manager to the latest version. Currently I have Yubikey Manager 1.2.6 installed on my Laptop. I restarted Fortify on my Laptop.

Still I see only Client certificate in the Web Developer tools. peculiar RSASSA-PSS Yubiko PIV lib

Fortify logs shows that libykcs11.dll library used is from Yubico PIV tool. {"level":"info","library":"C:\Program Files\Yubico\Yubico PIV Tool\bin\libykcs11.dll","message":"Loading PKCS#11 library","source":"provider","timestamp":"2024-05-27T07:10:38.716Z"}

Please find attached Fortify Logs: Fortify_logs_Yubiko_PIV_tool_library.txt

pmhatre-swi commented 1 month ago

Hi @microshine

Can you please check at your end whether entire certificate chain is fetched by the example that you have created? https://peculiarventures.github.io/fortify-examples/example6.html

Please find attached certificate chain that we are using on our Yubikey [with RSASSA-PSS algorithm] RSASSA-PSS Certificate chain.zip

microshine commented 1 month ago

Currently I have Yubikey Manager 1.2.6 installed on my Laptop

I'm not sure that Yubikey Manager contains PKCS#11 library. libykcs11.dll is part of Yubico PIV Tool. Please update it.

Can you please check at your end whether entire certificate chain is fetched by the example that you have created? https://peculiarventures.github.io/fortify-examples/example6.html

Please find attached certificate chain that we are using on our Yubikey [with RSASSA-PSS algorithm] RSASSA-PSS Certificate chain.zip

I'll check it and share the result shortly

microshine commented 1 month ago

Can you please check at your end whether entire certificate chain is fetched by the example that you have created? https://peculiarventures.github.io/fortify-examples/example6.html

I tried fetching the list of certificates and building the chain on my Yubikey using the provided link. The screenshot (attached) shows that the chain consists of 3 certificates. A total of 4 certificates were extracted from the token. The certificate not included in the chain is the key attestation certificate.

image image image

Please find attached certificate chain that we are using on our Yubikey [with RSASSA-PSS algorithm] RSASSA-PSS Certificate chain.zip

I attempted to build the certificate chain. The @peculiar/x509 module constructs the chain, but there is an issue with importing public keys from the certificates in the browser. The public keys use the RSA-PSS algorithm instead of RsaEncryption, which causes the browser's native cryptography to reject the public key in SPKI format. This results in an error and prevents the full path from being built.

I ran a similar setup on NodeJS, and the construction was successful because NodeJS uses a different crypto provider that supports this algorithm for public keys.

To resolve this issue in the browser, we can extend the x509 module to add the capability to convert such keys into a browser-supported format. This could involve either re-encoding the SPKI with the RsaEncryption algorithm or converting the SPKI to JWK.

This problem occurs in both Chrome and Safari browsers.

Example of RSA-PSS Key Structure in ASN.1 (formatted)

SEQUENCE (2 elem)
  SEQUENCE (2 elem)
    OBJECT IDENTIFIER 1.2.840.113549.1.1.10 rsaPSS (PKCS #1)
    SEQUENCE (3 elem)
      [0] (1 elem)
        SEQUENCE (1 elem)
          OBJECT IDENTIFIER 2.16.840.1.101.3.4.2.1 sha-256 (NIST Algorithm)
      [1] (1 elem)
        SEQUENCE (2 elem)
          OBJECT IDENTIFIER 1.2.840.113549.1.1.8 pkcs1-MGF (PKCS #1)
          SEQUENCE (1 elem)
            OBJECT IDENTIFIER 2.16.840.1.101.3.4.2.1 sha-256 (NIST Algorithm)
      [2] (1 elem)
        INTEGER 222
  BIT STRING (2160 bit) 001100001000001000000001000010100000001010000010000000010000000100000…
SEQUENCE (2 elem)
  INTEGER (2048 bit) 271189003140513352642996286075904296179645053014555503155676400457157…
  INTEGER 65537

Example of the Same Key with RsaEncryption OID

SEQUENCE (2 elem)
  SEQUENCE (2 elem)
    OBJECT IDENTIFIER 1.2.840.113549.1.1.1 rsaEncryption (PKCS #1)
    NULL
  BIT STRING (2160 bit) 001100001000001000000001000010100000001010000010000000010000000100000…
SEQUENCE (2 elem)
  INTEGER (2048 bit) 271189003140513352642996286075904296179645053014555503155676400457157…
  INTEGER 65537

By making these adjustments, we can ensure compatibility with browser cryptography APIs and successfully build the certificate chain in Chrome and Safari.

microshine commented 1 month ago

@pmhatre-swi I have updated and published a new build for @peculiar/x509. The module now re-encodes SPKI for RSA-PSS keys to RsaEncryption, which resolves the issue with public key export in the browser. Additionally, I have updated https://peculiarventures.github.io/fortify-examples/example6.html to use the latest version of @peculiar/x509. Now, certificate chain building for the provided RSA-PSS certificates works correctly in the browser.

microshine commented 1 month ago

I have managed to resolve the issue with using Yubico on Windows. The problem was that Fortify could not load the necessary dependencies from the Yubico directory when loading the module. This can be fixed by adding the path C:\Program Files\Yubico\Yubico PIV Tool\bin to the environment variable PATH.

Here are the steps to resolve this issue:

  1. Update the Fortify configuration in ~/.fortify/card.json. Replace %WINDIR/System32/libykcs11-1.dll for the 993988460d8f49a2ac519a2935f00533 driver with C:\\Program Files\\Yubico\\Yubico PIV Tool\\bin\\libykcs11.dll.
  2. Add the path to the environment variable. Example terminal command:
    setx PATH "%PATH%;C:\Program Files\Yubico\Yubico PIV Tool\bin"
  3. Restart Fortify.
  4. Check the Fortify logs to ensure the module loads without errors.

image

pmhatre-swi commented 1 month ago

Hi @microshine,

I tried above steps. I updated fortify configuration in ~/.fortify/card.json with C:\Program Files\Yubico\Yubico PIV Tool\bin\libykcs11.dll library from Yubico PIV Tool Also added the path to Windows Environment variable. Restarted Fortify.

Below are my observations.

  1. Verified from the Fortify logs that libykcs11.dll library is fetched from Yubico PIV Tool.

{"level":"info","library":"C:\Program Files\Yubico\Yubico PIV Tool\bin\libykcs11.dll","message":"Loading PKCS#11 library","source":"provider","timestamp":"2024-05-28T07:01:42.718Z"} {"level":"info","message":"Looking for slot","slots":1,"source":"provider","timestamp":"2024-05-28T07:01:43.798Z"} {"level":"info","message":"Use ConfigTemplateBuilder","source":"provider","timestamp":"2024-05-28T07:01:44.404Z"} {"cryptokiVersion":{"major":2,"minor":40},"firmwareVersion":{"major":1,"minor":0},"level":"info","library":"C:\Program Files\Yubico\Yubico PIV Tool\bin\libykcs11.dll","libraryVersion":{"major":2,"minor":52},"manufacturerId":"Yubico (www.yubico.com)","message":"PKCS#11 library information","source":"provider","timestamp":"2024-05-28T07:01:44.405Z"} {"id":"0bbb1473a9c09487d6bca1506a5865b14bdd061f1661c10b29b61ae35d3af469","level":"info","library":"C:\Program Files\Yubico\Yubico PIV Tool\bin\libykcs11.dll","message":"Crypto provider was added to the list","name":"Yubico Yubikey 4 OTP+U2F+CCID","reader":"Yubico YubiKey OTP+FIDO+CCID 0","source":"provider","timestamp":"2024-05-28T07:01:44.406Z"}

  1. Verified that Yubico PIV Tool Path is added successfully to Windows Environment Path. Environment Path on windows

  2. On the " https://peculiarventures.github.io/fortify-examples/example6.html " All certificates are displayed on Web developer console but not visible on the web page. Web developer console logs.txt

  3. Only Yubico PIV attestation certificate is visible on the web page. No other certificate option available under certificates. Certificate options available Certificate chain building example

microshine commented 1 month ago

Let's try another approach to retrieve the list of certificates using the pkcs11-tool utility from the OpenSC package.

Please follow these steps:

  1. Download and install OpenSC from this link.

  2. Open a terminal.

  3. Execute the following command to list certificate objects from the ykcs11 module for slot index 0:

    & 'C:\Program Files\OpenSC Project\OpenSC\tools\pkcs11-tool.exe' -O --module 'C:\Program Files\Yubico\Yubico PIV Tool\bin\libykcs11.dll' --slot-index 0 --type cert --pin 123456

Example output:

Using slot with index 0 (0x0)
Certificate Object; type = X.509 cert
  label:      X.509 Certificate for Digital Signature
  subject:    DN: CN=End-entity RSA-PKCS1
  serial:     2799F4C7527B299300116C7AA76C926B
  ID:         02
Certificate Object; type = X.509 cert
  label:      X.509 Certificate for Retired Key 1
  subject:    DN: CN=Intermediate ECDSA
  serial:     051115094A63457CA0D20C3E9B691896
  ID:         05
Certificate Object; type = X.509 cert
  label:      X.509 Certificate for Retired Key 2
  subject:    DN: CN=Root RSA-PSS
  serial:     467DC73AD55ADD3C30532F2A49A75F9D
  ID:         06
Certificate Object; type = X.509 cert
  label:      X.509 Certificate for PIV Attestation
  subject:    DN: CN=Yubico PIV Attestation
  serial:     FC721B77F363B46E
  ID:         19
Certificate Object; type = X.509 cert
  label:      X.509 Certificate for PIV Attestation 9c
  subject:    DN: CN=YubiKey PIV Attestation 9c
  serial:     01A97918E98A04C364EF28B55A4B60A8
  ID:         02

If OpenSC shows all necessary certificates, it may indicate an issue within Fortify. If it returns only two certificates, it could point to a limitation or configuration issue with the ykcs11 module (e.g., module version, missing certificates, token-specific behavior).

Let me know the output of this command so we can further diagnose the issue.

pmhatre-swi commented 1 month ago

Due to organization security reason, I need to take IT permission to install OpenSC on our Laptop. This process will take some time.

Meanwhile, Can you try to upload certificate chain (Client cert, Intermediate cert and Root cert) on your Yubikey and try the same with OpenSC? I have already attached certificate chain in the github ticket. RSASSA-PSS Certificate chain.zip

pmhatre-swi commented 1 month ago

We tried to retrieve list of certificates using pkcs11-tool utility from the OpenSC package. We have following observations.

  1. pkcs11-tool utility from OpenSC displays all the certificate present on the Yubikey including the certificates present in the hidden slots of the Yubikey.

OpenSC Yubico module output

  1. As mentioned in the previous observation, https://peculiarventures.github.io/fortify-examples/example6.html displays only Yubico PIV Attestation, not the other certificates.
pmhatre-swi commented 3 weeks ago

We are able to generate the certificate chain with RSASSA-PSS algorithm with below conditions using fortify example: https://peculiarventures.github.io/fortify-examples/example6.html

Pre-requisites:

  1. Fortify and Yubikey Manager is already installed on Laptop.
  2. RSASSA-PSS Client certificate is loaded on Yubikey slot 9a (Authentication)
  3. RSASSA-PSS Intermediate certificate is loaded on Yubikey slot 9d (Key Management)
  4. RSASSA-PSS Root certificate is loaded on Yubikey hidden slot 82 [Root certificate on Yubikey is not required for our application, Uploaded to hidden slot to test the entire certificate chain.]

Entire certificate chain is generated with Fortify Example with above steps.