Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot sign with signtool: No private key is available. #17

Open
dantheperson opened this issue Aug 7, 2023 · 8 comments
Open

Cannot sign with signtool: No private key is available. #17

dantheperson opened this issue Aug 7, 2023 · 8 comments

Comments

@dantheperson
Copy link

I have followed the example using a self signed cert to test: "Signing Windows Artifacts" https://cloud.google.com/kms/docs/reference/cng-signtool
But i get the error SignTool Error: No private key is available.

gcloud kms keys create dan-test --keyring build-ring --project xm-cloudbuild --location us --purpose "asymmetric-signing" --default-algorithm "ec-sign-p256-sha256" --protection-level "hsm"
openssl req -new -x509 -days 3650 -subj '/CN=test/' -sha256 -engine pkcs11 -keyform engine -key pkcs11:object=dan-test > ca.cert

C:\certificate\dan\new>type c:\Windows\KMSCNG\config.yaml
---
resources:
  - crypto_key_version: "projects/xm-cloudbuild/locations/us/keyRings/build-ring/cryptoKeys/bc-connector-sign-ec-2/cryptoKeyVersions/1"
  - crypto_key_version: "projects/xm-cloudbuild/locations/us/keyRings/build-ring/cryptoKeys/dan-test/cryptoKeyVersions/1"


"SIGNTOOL.EXE" sign ^
More?   /v /debug /fd sha256 /t http://timestamp.digicert.com ^
More?   /f ca.cert ^
More?   /csp "Google Cloud KMS Provider" ^
More?   /kc projects/xm-cloudbuild/locations/us/keyRings/build-ring/cryptoKeys/dan-test/cryptoKeyVersions/1 ^
More?   my.app

The following certificates were considered:
    Issued to: test
    Issued by: test
    Expires:   Thu Aug 04 02:49:06 2033
    SHA1 hash: 3D7D816E2E68EA4671621CEB31C89340157C1EB8

After EKU filter, 1 certs were left.
After expiry filter, 1 certs were left.
The following certificate was selected:
    Issued to: test
    Issued by: test
    Expires:   Thu Aug 04 02:49:06 2033
    SHA1 hash: 3D7D816E2E68EA4671621CEB31C89340157C1EB8

SignTool Error: No private key is available.

if i then import the certificate using windows mmc and run repair to associate the private key, i get the following error regarding unsupported legacy key spec

Is there anything else i can do to debug the issue?

certutil -user -repairstore My 3D7D816E2E68EA4671621CEB31C89340157C1EB8
My "Personal"
================ Certificate 4 ================
Serial Number: 514da11934da497ed7c7f7cb1cbec8bf79cdb233
Issuer: CN=test
 NotBefore: 07/08/2023 02:49
 NotAfter: 04/08/2033 02:49
Subject: CN=test
Signature matches Public Key
Root Certificate: Subject matches Issuer
Cert Hash(sha1): 3d7d816e2e68ea4671621ceb31c89340157c1eb8
  Key Container = projects/xm-cloudbuild/locations/us/keyRings/build-ring/cryptoKeys/dan-test/cryptoKeyVersions/1
I0807 02:56:27.243154    4272 logging.cc:81] returning 0x80090027 from OpenKeyFn due to status INVALID_ARGUMENT: at bridge.cc:187: unsupported legacy key spec specified: 0 [type.googleapis.com/kmscng.StatusDetails='SECURITY_STATUS=0x80090027']
  Provider = Google Cloud KMS Provider
I0807 02:56:27.244982    4272 logging.cc:81] returning 0x80090029 from SetProviderPropertyFn due to status NOT_FOUND: at provider.cc:108: unsupported property specified [type.googleapis.com/kmscng.StatusDetails='SECURITY_STATUS=0x80090029']
I0807 02:56:27.245626    4272 logging.cc:81] returning 0x80090027 from OpenKeyFn due to status INVALID_ARGUMENT: at bridge.cc:187: unsupported legacy key spec specified: 0 [type.googleapis.com/kmscng.StatusDetails='SECURITY_STATUS=0x80090027']
Encryption test FAILED
CertUtil: -repairstore command completed successfully.

Public key matches

C:\certificate\dan\new>gcloud kms keys versions get-public-key --keyring build-ring --key dan-test --location us --project xm-cloudbuild 1
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEk6ALoGc+vV2Jod/BV98qxxqbIlWY
XJ3sdaYAEECvM9c/Xvi9cHnk72OQhRtJb6zJiQs8i/HgxmukNOHSzjTVCg==
-----END PUBLIC KEY-----


Updates are available for some Google Cloud CLI components.  To install them,
please run:
  $ gcloud components update


C:\certificate\dan\new>openssl x509 -in ca.cert -pubkey -noout
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEk6ALoGc+vV2Jod/BV98qxxqbIlWY
XJ3sdaYAEECvM9c/Xvi9cHnk72OQhRtJb6zJiQs8i/HgxmukNOHSzjTVCg==
-----END PUBLIC KEY-----
@pwae
Copy link

pwae commented Aug 8, 2023

Hi @dantheperson,
I've been working on getting our CI/CD process over to signing via this too. It's been a bit "fun" and maybe later i'll contribute some formal docs.

Here's what i have been doing to setup initially:

  1. set the environment variable GOOGLE_APPLICATION_CREDENTIALS to the path to my service account json file (e.g. set GOOGLE_APPLICATION_CREDENTIALS=c:\service-account.json)
  2. set KMS_CNG_VERBOSE to 1 (e.g. set KMS_CNG_VERBOSE=1)
  3. Make sure i have done the bit at the bottom of the FAQ about the PEM root certs https://github.com/GoogleCloudPlatform/kms-integrations/blob/master/kmscng/docs/user_guide.md#faqs
  4. Make sure i have a new version of Windows SDK installed. (Initially tests using a pre existing version did not work at all)

if you have done that, and have the KMS CNG installed, you can do the following to see if it is working ok:
certutil -csp "Google Cloud KMS Provider" -csptest

If it is, you should see some output similar to the below from the debug switch.
image

If you don't, do a certutil -csplist and validate you see "Google Cloud KMS Provider" in there.

If it is working, and you attempt to sign, you should see more output this time hopefully.

Here's the command I used for a test sign:

"C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64\signtool.exe" sign /debug /v /fd sha256 /td sha256 /d "APP_DESCRIPTION" /du https://app.link/url/ /f "C:\path\to\cert.crt" /tr http://timestamp.digicert.com /csp "Google Cloud KMS Provider" /kc "projects/PROJECT_ID/locations/LOCATION_ID/keyRings/KEYRING_ID/cryptoKeys/KEYNAME/cryptoKeyVersions/KEY_VERSION" test-script.ps1

Hopefully this gives you some more output and points in the right direction.

Cheers,
Scott

@bdhess
Copy link
Contributor

bdhess commented Aug 8, 2023

I also suspect that the root cause is the root certs

Sorry that this is opaque - we are going to do our best to fix it for the GA release

@dantheperson
Copy link
Author

Thanks for the input, you're right i had set the root certs when running certutil repair, as that gave me the error tha tthe FAQ mentions, but I hadn't tried that when running SignTool. Unfortuantly it make no difference, no extra debug output either.

C:\certificate\dan\new>set KMS_CNG_VERBOSE=1

C:\certificate\dan\new>set GRPC_DEFAULT_SSL_ROOTS_FILE_PATH=c:\certificate\dan\new\roots.pem

C:\certificate\dan\new>"SIGNTOOL.EXE" sign ^
More?   /v /debug /fd sha256 /t http://timestamp.digicert.com ^
More?   /f ca.cert ^
More?   /csp "Google Cloud KMS Provider" ^
More?   /kc projects/xm-cloudbuild/locations/us/keyRings/build-ring/cryptoKeys/dan-test/cryptoKeyVersions/1 ^
More?   my.app

The following certificates were considered:
    Issued to: test
    Issued by: test
    Expires:   Thu Aug 04 02:49:06 2033
    SHA1 hash: 3D7D816E2E68EA4671621CEB31C89340157C1EB8

After EKU filter, 1 certs were left.
After expiry filter, 1 certs were left.
The following certificate was selected:
    Issued to: test
    Issued by: test
    Expires:   Thu Aug 04 02:49:06 2033
    SHA1 hash: 3D7D816E2E68EA4671621CEB31C89340157C1EB8

SignTool Error: No private key is available.

For the service account, i'm using the service account assigned to the GCE VM, so i haven't set any variables for that. The glcoud kms commands against the key, e.g. get-public-key work ok from the machine.

The SA is setup like so:

resource "google_service_account" "bc_connector_signing" {
  account_id   = "redacted"
  display_name = "bc-connector-sign"
}

resource "google_project_iam_binding" "cloudkms_signer" {
  project = "xm-cloudbuild"
  role    = "roles/cloudkms.signerVerifier"

  members = [
    "serviceAccount:${google_service_account.bc_connector_signing.email}"
  ]
}

# To repair certstore
resource "google_project_iam_binding" "cloudkms_viewer" {
  project = "xm-cloudbuild"
  role    = "roles/cloudkms.viewer"

  members = [
    "serviceAccount:${google_service_account.bc_connector_signing.email}"
  ]
}

I've attached the certutil -csptest output, it's quite large, with quite a few log messages from the KMS provider. Not sure what is normal as I expect with only a few functions being implemented in the provider, a few failures/warnings would be normal?

Windows Version in case it's relevant

Edition	Windows Server 2022 Datacenter
Version	21H2
Installed on	‎04/‎05/‎2022
OS build	20348.1850

csptest.txt

@pwae
Copy link

pwae commented Aug 9, 2023

Given that csptest is showing it's calling the KMS CNG library (the extra output is from the KMS_CNG_VERBOSE flag), i suspect the problem may be your version of signtool.exe

I'm not sure if its x86/x64 thing, or what.. but I've seen certain versions just act like the Google KMS provider doesn't exist.

I've had the version (installed with the Windows SDK) work perfectly.
Installed at the location: C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64\signtool.exe

I've also tried with older versions (that were pre-existing in our build pipeline) of 10.0.10586.212 and 6.1.7600.16385 that just didn't work at all.

@dantheperson
Copy link
Author

Thank you so much @pwae
It was the arch version of SignTool. The x86 version was on the path, once i used the full path to the x64 it worked. In my case: "C:\Program Files (x86)\Windows Kits\10\bin\10.0.22000.0\x64\SIGNTOOL.EXE"

@bdhess
Copy link
Contributor

bdhess commented Aug 10, 2023

+1 - thanks very much @pwae for documenting your findings. I'm going to leave this open for now, to remind us to do a better job of documenting the expected behavior from x86 versions of signtool.

And as an update on the root certs issue, I think we have a solution that will make it into the GA release, so one fewer hurdle there.

@obones
Copy link

obones commented Sep 11, 2023

Thanks for those detailed explanations, it fixed the issue I was facing as well.

There is one thing however:
having only an x64 version of the provider is annoying as it prevents using "Microsoft Office Subject Interface Packages" to digitally sign Office related files.
Indeed those SIPS dlls are only compatible with the x86 version of signtool.
Would it be possible to consider having a x86 version as well?

@tdbhacks
Copy link
Member

Hi @obones, an x86 version of the provider is technically possible, but not part of our core target CUJs for the initial GA launch. That said, we're definitely interested in hearing about potential areas of improvement and future work, do you mind creating a new issue in this repo so that we can track it as a feature request?

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants