Microsoft Key Storage Provider get keys - c++

I am trying to get the details of keys in Microsoft Key Storage Provider.
For this I open the storage provider using the below API call:
NCryptOpenStorageProvider(&prov, MS_KEY_STORAGE_PROVIDER, 0);
Then I call NCryptEnumKeys in a while loop to get the key details.
However I am only able to get one key from the KSP.
During the second iteration of the loop NCryptEnumKeys returns NTE_NO_MORE_ITEMS.
But I have at-least 3 certificates in my local machine store that have Microsoft Key Storage Provider as Provider.
I have confirmed the same through certutil -store my command.
What could possibly be wrong?

After days of analysis and discussions, finally I was able to identify the root cause. It is related to privileges. If I run with Admin privilege, I can extract keys for ECDSA certificate as well from the Local Machine certificate store.
If you do not intend to use Admin privilege, just take the certificate manager or mmc and select the certificate, take All tasks > Manage Private Keys give privileges as required.

Related

Access keys for Local Machine from Microsoft KSP

The below powershell command correctly lists all the keys for my local machine store:
certutil -csp "Microsoft Software Key Storage Provider" -key
However, I am not able to do the same through C++ code using NCryptOpenStorageProvider and NCryptOpenKey APIs. I suspect that NCryptOpenStorageProvider is not giving me the list that includes Local Machine keys. My API usage is as below:
NCryptOpenStorageProvider(&prov, MS_KEY_STORAGE_PROVIDER, 0);
NCryptOpenKey(prov, &keyHandle, pCryptKeyProvInfo->pwszContainerName, 0, NCRYPT_MACHINE_KEY_FLAG);
Can someone provide a clue on this?
Thanks in advance.
Additional info:
certutil -csp "Microsoft Software Key Storage Provider" -key returns NULL when run normally, but gives the proper list of keys only when run with Admin privilge.
So, I assume it has something to do with privileges.
Can someone suggest where I can update the privileges for my KSP corresponding to Local Machine?

signtool fails to sign a binary with a key from a AWS CloudHSM

We are going to use AWS CloudHSM service to keep all code signing certificates secure and perform code signing on our build server. Our build server is Windows Server 2010, so I installed AWS CloudHSM client there. I activated cluster and all commandline utils work as expected: I am able to login, add keys, find keys etc. We would like to continue to use signtool to sign our binaries, so I thought that we can use key storage providers (KSPs) for AWS CloudHSM, that are installed along with other tools.
The Cavium KSP and CNG providers were installed successfully and are visible in the windows crypto provider's list. I defined environment variables as said here ( https://docs.aws.amazon.com/cloudhsm/latest/userguide/ksp-library-prereq.html ).
I added certificate via certutil to the HSM storage:
Certutil -CSP "Cavium Key Storage Provider" -user -importPFX "certificate.pfx"
SDK Version: 2.03
Enter PFX password:
Certificate "myCertificate" added to store.
CertUtil: -importPFX command completed successfully.
Certificate has been added sucessfully and it appears when I execute findKey command from key_mgmt_util.exe console.
After that I tried to sign a binary with the certificate as it is said in https://learn.microsoft.com/en-us/windows-hardware/test/hlk/user/hlk-signing-with-an-hsm:
signtool_64 sign /n myCertificate "test.exe"
or
signtool sign /sha1 4F555EF9FAB8E86A2F84ACF325362A29FB64AF66 "test.exe"
but I got an error I cannot resolve
SDK Version: 2.03
Done Adding Additional Store
SignTool Error: An error occurred while attempting to load the signing
certificate from: C:\temp\test.exe
I also tried to specify key storage provider and key container
signtool sign /csp "Cavium Key Storage Provider" /k CARoot-877f51a1-90ee-4c10-8feb-02925caab4fb test.exe
that returned to me
SignTool Error: An unexpected internal error has occurred.
Error information: "Could not associate private key with certificate." (-2147024
891/0x80070005)
and
signtool sign /f certificate.pem /csp "Cavium Key Storage Provider"
/k CARoot-877f51a1-90ee-4c10-8feb-02925caab4fb test.exe
with other error message
SignTool Error: The specified private key does not match the public key of the selected certificate.
It seems to me that something is wrong with the certificate from the storage, but I have no idea how to fix this. test.exe exists on the disk and can be signed with signtool using certificate from another provider or when specifiyng pfx file.
What am I doing wrong? Is Amazon CloudHSM client compatible with signtool or how else can I sign binary on Windows using Amazon CloudHSM as a key storage?
I just wrote the article Signing executables with Microsoft SignTool.exe using AWS CloudHSM-backed certificates that covers this scenario.
To summarize:
You need to ensure that you have the latest binaries for CloudHSM.
Check that when the certificate is created (if you self sign) that the relevant Key Container within Windows is created.
Run certutil -repairstore if needed.
When using the SignTool, check that you specify the
certificate HASH
If you need further help, reach out to AWS Support as always or look in the AWS forums.
I wrote to AWS supported and they responded back with:
"This issue seems to be caused by trying to store the certificate on the HSM, and referencing the certificate with SignTool. Although the certutil command shows "CertUtil: -importPFX command completed successfully.", CloudHSM doesn't currently support certificate storage. This feature will be added however, and when it's released will be added to the version history page.
You should be able to use SignTool by referencing the certificate locally (.crt/.cer), and using the private key of the certificate stored on the HSM:
c:> signtool sign /f certname.cer /csp "Cavium Key Storage Provider" /k kontainer_name test.exe
But this approach doesn't work on my end either. So I am still waiting for their assistance
Have you tried
setx /m n3fips_partition <my hsm id>
setx n3fips_password=CU-username:CU-password
signtool sign /f /csp "Cavium Key Storage Provider" /k <container name> test.exe
I don't know what the container name should be. Usually there's a tool to map between the HSM partition and a container.
cloudhsm v2 docs on this topic can be found her https://docs.aws.amazon.com/cloudhsm/latest/userguide/ksp-library-prereq.html
https://learn.microsoft.com/en-us/windows/desktop/seccrypto/signtool
Searching through the registry for Cavium I found
Cavium CNG Provider and Cavium Key Storage Provider . maybe you need the cng which maps to ksp?
Also, The doc for the project is on github and the doc writers appear to be contributors
https://github.com/awsdocs/aws-cloudhsm-user-guide/blob/master/doc_source/ksp-library-install.md
Did you run the csp ksp registration tool?

access credentials error in Copy Command in S3

I am facing access credentials error when i ran copy Command in S3.
my copy command is :
copy part from 's3://lntanbusamplebucket/load/part-csv.tbl'
credentials 'aws_access_key_id=D93vB$;yYq'
csv;
error message is:
error: Invalid credentials. Must be of the format: credentials 'aws_iam_role=...' or 'aws_access_key_id=...;aws_secret_access_key=...[;token=...]'
'aws_access_key_id=?;
aws_secret_access_key=?''
Could you please can any one explain what is aws_access_key_id and aws_secret_access_key ?
where we can see this?
Thanks in advance.
Mani
The access key you're using looks more like a secret key, they usually look something like "AKIAXXXXXXXXXXX".
Also, don't post them openly in StackOverflow questions. If someone gets a hold of a set of access keys, they can access your AWS environment.
Access Key & Secret Key are the most basic form of credentials / authentication used in AWS. One is useless without the other, so if you've lost one of the two, you'll need to regenerate a set of keys.
To do this, go into the AWS console, go to the IAM services (Identity and Access Management) and go into users. Here, select the user that you're currently using (probably yourself) and go to the Security Credentials tab.
Here, under Access keys, you can see which sets of keys are currently active for this user. You can only have 2 sets active at one time, so if there's already 2 sets present, delete one and create a new pair. You can download the new pair as a file called "credentials.csv" and this will contain your user, access key and secret key.

Importing Key Pair into Amazon AWS - wrong fingerprint?

I'm trying to import an existing keypair from my computer to use in EC2. But once I click "Yes, Import", the fingerprint Amazon shows doesn't match the fingerprint shown by ssh -lf for the same key. I've verified that they're the same key, tried reimporting the key, etc. The common practice seems to be to use the "Create Key Pair" part instead, but I'd prefer to use my usual SSH keypair. I'm also unable to login using SSH into an instance that's set to use this keypair (I get Permission denied (publickey).).
Has anyone encountered such issues with AWS? Any insights into what the issue might be?
There seems to be an answer in the AWS forums for the fingerprint difference. I'm pasting the content here for posterity:
Hello,
I discussed with my colleagues and looks like it is a limitation from
our end to provide keypair in different format. You'll notice the
different lengths of the Amazon-generated Key Pair and the Import Key
Pair. In the case of an Amazon-generated Key Pair, the Fingerprint is
for the Private Key, while if you use Import Key Pair the fingerprint
is for your public key. Amazon does not retain a copy of the generated
Private Key, but the EC2 command line tools do provide a way to
reproduce the SSH2 MD5 fingerprint:
ec2-fingerprint-key ./testpair1-private.pem
61:26:cc:7d:2a:2c:a4:e9:fb:86:ca:ef:57:d6:68:f8:24:bc:59:cd
This should match what you see in the console for the region in which
you created the key, such as US-West-1 (North California).
Unfortunately the ec2-fingerprint-key command-line tool does not
fingerprint public keys. If you import the public key in another
region such as US-East-1, the web AWS Console will only display the
fingerprint of the public key.
Secondly, the AWS Console should be more clear on exactly what type of
fingerprint it displays, which is the "MD5 public key fingerprint as
specified in section 4 of RFC4716" (also known as SSH2 format) as
mentioned here:
http://docs.amazonwebservices.com/AWSEC2/latest/CommandLineReference/ApiReference-cmd-ImportKeyPair.html
We have already put in a feature request for the web-based AWS Console
to support the more common OpenSSH format. Unfortunately I was not
able to find any user-friendly tools to generate the SSH2/RFC4716
format fingerprint, though I did find that you can import the same
public key in your original region (with a name such as "Test2") and
match the shown fingerprint between regions.
(emphases mine)
As he mentions, I too wasn't able to locate any tool to generate the SSH2/RFC4716 format fingerprint. This at least solves the mystery of mismatching fingerprints (at least if we assume ssh-keygen -lf gives output in the "more common OpenSSH format", please correct me if this assumption is wrong); I'm still getting a Permission denied (publickey) when i try to ssh, but I'll assume it's not an actual key mismatch now and explore other avenues.
Here's an alternative way to verify finger print:
openssl pkcs8 -in my-aws-key.pem -nocrypt -topk8 -outform DER | openssl sha1 -c

Amazon CloudFront key-pair creation

From my "Security Credentials", I can NOT create any more key pairs for my CloudFront setup.
I can only see my existing 2 key pairs and my deleted one. The "create" link is not present.
Do you have a reason for that?
How can I create key pairs without using this interface?
How can I bring back the feature to create key pair from that interface?
It's not possible to have more than two key pairs available for use at any one point in time, see Access Credential Rotation:
[...] you can have two credentials in an Active state at any point in time
so you can rotate them without impact to your application's
availability. The AWS Security Credentials page displays the current
state of each of the credentials you can rotate. The possible states:
Active—Can be used to secure requests to AWS.
Inactive—Can't be used, but can be moved back to the Active state.
Deleted—Can never be used again.
The first sentence is actually a bit misleading, insofar it applies to key pairs in the Inactive state as well, because these can be activated again.
As soon as you delete an inactive key, you will be able to create a new one.