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
113 stars 32 forks source link

Signing via website demo - CKR_FUNCTION_FAILED #581

Open Inso2008 opened 2 months ago

Inso2008 commented 2 months ago

Hello,

in connection with the transition of our web systems from another cross-browser certificate handler I wanted to try the process of signing with certificate via demo on https://fortifyapp.com/examples#signing.

I have valid certificates (they are working elsewhere), but am unable to make it happen due to some unspecific error. I have newest build of Fortify (v2.0.1) installed on several machines (all Windows x64). I tried on various browsers (Logs and screens from Chrome v128.0.6613.85 attached).

Any ideas what can I try to go through?

fortifyapp.com-1724682529724.log fortify_err fortify_err_con

microshine commented 2 months ago

@Inso2008 Can you enable log using Fortify Preferences, restart Fortify, sign document and share the Fortify log?

Inso2008 commented 2 months ago

fortify.log

Here it is.

microshine commented 2 months ago

As I can see from the logs, the error occurs at the moment of signing the data using the RSASSA-PKCS1-v1_5 mechanism in combination with SHA-256. During the signing process, the application uses the Windows Crypto API provider, which operates through the pvpkcs11 module. This module supports logging, as documented here:

https://github.com/PeculiarVentures/pvpkcs11/blob/master/README.md#enviroment-variables

If you enable error output for the pvpkcs11 module, you can get a more detailed description of the error.

Here’s an example log entry:

{"message":"sign","source":"server-api","crypto":"Windows CryptoAPI","algorithm":{"name":"RSASSA-PKCS1-v1_5","hash":"sha-256"},"key":{"algorithm":{"name":"RSASSA-PKCS1-v1_5","hash":"SHA-256","token":true,"sensitive":false},"type":"private","extractable":false,"usages":["decrypt","sign","unwrapKey"],"id":"445aec151ad1e9fd82173bbd41586a8f5b3e7a94"}}
{"message":"Server event error","source":"server","error":"CKR_FUNCTION_FAILED","stack":"Pkcs11Error: CKR_FUNCTION_FAILED\n    at prepareError (C:\\snapshot\\fortify-app\\node_modules\\pkcs11js\\index.js:58:12)\n    at C:\\snapshot\\fortify-app\\node_modules\\pkcs11js\\index.js:94:19"}

To better understand the issue:

Inso2008 commented 2 months ago

Yes, thank you very much for directions - here they are:

PVPKCS11.log fortify.log

microshine commented 2 months ago

Based on the logs, there seems to be a problem with how a key is being used:

ERROR  C_Sign Exception: NTException: NTException(0x80090029) NCryptSignHash The requested operation is not supported.

This error is happening within the pvpkcs11 module, specifically within the part of the code that handles cryptographic signing using the CNG provider. You can review the problematic section here: crypto_sign.cpp#L145-L192.

The issue could be that the key doesn't support the operation you are trying to perform, or there might be a mistake in how the parameters are set up for your key in the module. To get a clearer picture, it would help to have more details about your key container. Please run the following PowerShell script to gather comprehensive information about your certificate and private key. This information will assist us in identifying the specific problem.

# List all certificates from the My store (index, name and thumbprint)
$certs = Get-ChildItem -Path Cert:\CurrentUser\My
$certs | ForEach-Object {
  [PSCustomObject]@{
    Index      = $certs.IndexOf($_)
    Subject    = $_.Subject
    Thumbprint = $_.Thumbprint
  }
} | Format-Table -AutoSize

# Prompt for a certificate index
$index = Read-Host -Prompt 'Enter the certificate index'

# Get the certificate by index
$cert = $certs[$index]

# Print general certificate information
Write-Host "Certificate Information:"
$cert | Format-List -Property *

if ($cert.HasPrivateKey -eq $false) {
  Write-Host "Certificate does not have an associated private key."
  exit
}
Write-Host "Certificate has an associated private key."

# Get the private key container information
$privateKey = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey($cert)
Write-Host "Private key information:"
if ($privateKey.GetType().Name -ieq "RSACng") {
  Write-Host "  Provider: $($privateKey.Key.Provider)"
  Write-Host "  Container: $($privateKey.Key.UniqueName)"
  Write-Host "  Key Usage: $($privateKey.Key.KeyUsage)"
  Write-Host "  Export Policy: $($privateKey.Key.ExportPolicy)"
  Write-Host "  Key Size: $($privateKey.Key.KeySize)"
  Write-Host "  Name: $($privateKey.Key.KeyName)"
  Write-Host "  Is Ephemeral: $($privateKey.Key.IsEphemeral)"
  Write-Host "  Is Machine Key: $($privateKey.Key.IsMachineKey)"
}
else {
  $csp = $privateKey.CspKeyContainerInfo
  Write-Host "  Provider: CSP"
  Write-Host "  Accessible: $($csp.Accessible)"
  Write-Host "  Exportable: $($csp.Exportable)"
  Write-Host "  Hardware Device: $($csp.HardwareDevice)"
  Write-Host "  Key Container Name: $($csp.KeyContainerName)"
  Write-Host "  Key Number: $($csp.KeyNumber)"
  Write-Host "  Machine Key Store: $($csp.MachineKeyStore)"
  Write-Host "  Protected: $($csp.Protected)"
  Write-Host "  Provider Name: $($csp.ProviderName)"
  Write-Host "  Provider Type: $($csp.ProviderType)"
  Write-Host "  Randomly Generated: $($csp.RandomlyGenerated)"
  Write-Host "  Removable: $($csp.Removable)"
  Write-Host "  Unique Key Container Name: $($csp.UniqueKeyContainerName)"
}
Inso2008 commented 2 months ago

Here it is. Hope it helps. This certificate should be valid - it is used for signing up our testing documents and outside Fortify it works.

CertificateInformation.txt