Discussion:
CryptAcquireContext fails with error (8009000F)
(too old to reply)
sachin
2004-05-11 07:11:27 UTC
Permalink
I am running the following code on XP machines. On some of the machines it
gives error 8009000F at the place that I have marked in the code ###. Error
description says "Object already exists." When does this error occur?

LPCSTR UserName = "MyName";

if (RCRYPT_FAILED(CryptAcquireContext(&hCryptProv, UserName,
MS_ENHANCED_PROV, PROV_RSA_FULL, 0) ) ){
if(GetLastError() == NTE_BAD_KEYSET){
if (RCRYPT_FAILED(CryptAcquireContext(&hCryptProv, UserName,
MS_ENHANCED_PROV,

PROV_RSA_FULL, CRYPT_NEWKEYSET) ) ){
printf("Could not get crypto context %x",GetLastError() );
#############ERROR###########
}
else{
return TRUE;
}
}
}
else{
return TRUE;
}
return FALSE;



Thanks,
Sachin
Sergio Dutra [MS]
2004-05-11 16:38:51 UTC
Permalink
It usually means you already have that container name but it was not created
by you and you do not have permissions on it. Hence, when you try to acquire
a context without any keyset flags it will give you bad keyset, but when you
try to create the keyset CryptAcquireContext will return that it already
exists.

You will need to try a different key container name.
--
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm
Post by sachin
I am running the following code on XP machines. On some of the machines it
gives error 8009000F at the place that I have marked in the code ###. Error
description says "Object already exists." When does this error occur?
LPCSTR UserName = "MyName";
if (RCRYPT_FAILED(CryptAcquireContext(&hCryptProv, UserName,
MS_ENHANCED_PROV, PROV_RSA_FULL, 0) ) ){
if(GetLastError() == NTE_BAD_KEYSET){
if (RCRYPT_FAILED(CryptAcquireContext(&hCryptProv, UserName,
MS_ENHANCED_PROV,
PROV_RSA_FULL, CRYPT_NEWKEYSET) ) ){
printf("Could not get crypto context %x",GetLastError() );
#############ERROR###########
}
else{
return TRUE;
}
}
}
else{
return TRUE;
}
return FALSE;
Thanks,
Sachin
sachin
2004-05-12 04:13:04 UTC
Permalink
I think the user name in my actual code is quite specific and should be
there only with my application. Now, what is a possible scenario when this
problem can come. e.g. If I am using the application from some shared server
and later on trying to run it locally ; or on the same machine I am running
it from different user accounts. When I faced the problem I tried to open
the container in Microsoft/Crypto directory and I was able to open or delete
it. I got one article with MS exchange server where in the problem case, it
was not possible to open the container and so we need to change the
ownership.

Thanks,
Sachin
Post by Sergio Dutra [MS]
It usually means you already have that container name but it was not created
by you and you do not have permissions on it. Hence, when you try to acquire
a context without any keyset flags it will give you bad keyset, but when you
try to create the keyset CryptAcquireContext will return that it already
exists.
You will need to try a different key container name.
--
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm
Post by sachin
I am running the following code on XP machines. On some of the machines it
gives error 8009000F at the place that I have marked in the code ###. Error
description says "Object already exists." When does this error occur?
LPCSTR UserName = "MyName";
if (RCRYPT_FAILED(CryptAcquireContext(&hCryptProv, UserName,
MS_ENHANCED_PROV, PROV_RSA_FULL, 0) ) ){
if(GetLastError() == NTE_BAD_KEYSET){
if (RCRYPT_FAILED(CryptAcquireContext(&hCryptProv, UserName,
MS_ENHANCED_PROV,
PROV_RSA_FULL, CRYPT_NEWKEYSET) ) ){
printf("Could not get crypto context
%x",GetLastError() );
Post by Sergio Dutra [MS]
Post by sachin
#############ERROR###########
}
else{
return TRUE;
}
}
}
else{
return TRUE;
}
return FALSE;
Thanks,
Sachin
lelteto
2004-05-11 22:26:04 UTC
Permalink
Try to use some application-unique container name. My method is to generate a GUID, get its character-string representation then append it to the name of my application. You normally put this into a #define in a separate header file

Laszlo Eltet
SafeNet, Inc.
Hao Zhuang [MSFT]
2004-07-30 07:35:23 UTC
Permalink
why dont you specify pinfo->pwszProvName in the CryptAcquireContext call ?

- hao
--
This posting is provided "AS IS" with no warranties, and confers no rights.
I am having a similar problem, where I CryptAcquireContext fails with
NTE_BAD_KEYSET. At that point I tried to generate a new container with
CRYPT_NEWKEYSET but that fails as well.
Any help will be appreciated.
I have attached a sample piece of code where I have the following 4
-loadCertificate takes in a hash and fills up PCRYPT_KEY_PROV_INFO struct
-ms2opensslX509 makes an ssl x509 cert out of it.
-ms2opensslRSANoPrivateKey tries to acquire the context
based on the information returned in PCRYPT_KEY_PROV_INFO.
However that function call fails when used on machine bootup.
The objective was to use the machine certificate on boot up for
authentication. The code that worked for machine and user
authentication (TLS) worked when the user had already logged in
and performed authentication through a desktop utility.
However, it fails "sometimes" when run in a service on boot up.
In the code below why does getCryptProv fail sometimes with error
key set does not exist. What is a workaround for that?
I tried CryptAcquireContext with CRYPT_NEWKEYSET flag if
it failed with NTE_BAD_KEYSET. That did not resolve it.
*/
static int loadCertificate( PCRYPT_HASH_BLOB pHash)
{
//....continued.....
DWORD keyFlags = 0;
if (pHash == NULL)
{
DWORD propId = CERT_KEY_PROV_INFO_PROP_ID;
if ( ( pCertContext = CertFindCertificateInStore
( hSystemStoreHandle,
X509_ASN_ENCODING,
0,
CERT_FIND_PROPERTY,
&propId,
pCertContext ) ) == NULL )
{
dbprint("Could not find a certificate with a NULL hash.\n");
res = 0;
goto end;
}
}
else
{
if ( ( pCertContext = CertFindCertificateInStore
( hSystemStoreHandle,
X509_ASN_ENCODING,
0,
CERT_FIND_HASH,
pHash,
pCertContext ) ) == NULL )
{
dbprint("Could not find a certificate with a given hash.\n");
res = 0;
goto end;
}
}
CertGetCertificateContextProperty(pCertContext,
CERT_KEY_PROV_INFO_PROP_ID, NULL, &cbData);
if ((pinfo = (PCRYPT_KEY_PROV_INFO)malloc(cbData)) == NULL)
{
res = 0;
goto end;
}
if (!CertGetCertificateContextProperty(pCertContext,
CERT_KEY_PROV_INFO_PROP_ID,
pinfo, &cbData))
{
dbprint("Error in CertGetCertificateContextProperty (%x)\n",
GetLastError());
res = 0;
goto end;
}
cert = ms2opensslX509(pCertContext->pbCertEncoded,
pCertContext->cbCertEncoded);
if (SSL_use_certificate(con, cert) != 1)
{
dbprint("Error in SSL_use_certificate\n");
res = 0;
goto end;
}
if ( global.machineKeyset )
{
keyFlags |= CRYPT_MACHINE_KEYSET;
}
key = ms2opensslRSANoPrivateKey(pinfo, keyFlags);
if (key == NULL) {
res = 0;
dbprint( "ms2opensslRSANoPrivateKey did not return a key\n" );
goto end;
}
//....continued.....
}
RSA *ms2opensslRSANoPrivateKey(PCRYPT_KEY_PROV_INFO pinfo, int flags)
{
//....continued.....
MSKeyContext *ctx;
if ((ctx = malloc(sizeof(MSKeyContext))) == NULL)
{
goto err;
}
if ((ctx->hCryptProv = getCryptProv(pinfo, flags)) == 0)
{
//!!!!!!!!!!!!!!! FAILS SOMETIMES WHY??!!!!!!!!!!!!!!//
// Error message is that a keyset does not exist //
// Why can it not find it? //
goto err;
}
//....continued.....
}
static HCRYPTPROV getCryptProv(PCRYPT_KEY_PROV_INFO pinfo, int flags)
{
HCRYPTPROV hProv = 0;
if(!CryptAcquireContext(
&hProv,
pinfo->pwszContainerName,
NULL,
pinfo->dwProvType,
flags))
{
//dbprint( "CrypAcquireContext failed\n" );
}
return hProv;
}
--
Yasir Ali
Software Engineer
Meetinghouse Data Communications
Post by sachin
I am running the following code on XP machines. On some of the machines it
gives error 8009000F at the place that I have marked in the code ###. Error
description says "Object already exists." When does this error occur?
LPCSTR UserName = "MyName";
if (RCRYPT_FAILED(CryptAcquireContext(&hCryptProv, UserName,
MS_ENHANCED_PROV, PROV_RSA_FULL, 0) ) ){
if(GetLastError() == NTE_BAD_KEYSET){
if (RCRYPT_FAILED(CryptAcquireContext(&hCryptProv, UserName,
MS_ENHANCED_PROV,
PROV_RSA_FULL, CRYPT_NEWKEYSET) ) ){
printf("Could not get crypto context
%x",GetLastError() );
Post by sachin
#############ERROR###########
}
else{
return TRUE;
}
}
}
else{
return TRUE;
}
return FALSE;
Thanks,
Sachin
Ryan Menezes [MSFT]
2004-07-30 07:52:26 UTC
Permalink
If you are using CryptAcquireContext in side a service and impersonating a
user, ensure that the user profile is loaded with LoadUserProfile.

If you get a combination of NTE_BAD_KEYSET and NTE_KEY_EXISTS for 0 and
CRYPT_NEWKEYSET with machine keys, it normally indicates you dont have the
correct ACLs on the key containers.
--
Thanks,
Ryan Menezes [MS]
This posting is provided "AS IS" with no warranties, and confers no rights.
I am having a similar problem, where I CryptAcquireContext fails with
NTE_BAD_KEYSET. At that point I tried to generate a new container with
CRYPT_NEWKEYSET but that fails as well.
Any help will be appreciated.
I have attached a sample piece of code where I have the following 4
-loadCertificate takes in a hash and fills up PCRYPT_KEY_PROV_INFO struct
-ms2opensslX509 makes an ssl x509 cert out of it.
-ms2opensslRSANoPrivateKey tries to acquire the context
based on the information returned in PCRYPT_KEY_PROV_INFO.
However that function call fails when used on machine bootup.
The objective was to use the machine certificate on boot up for
authentication. The code that worked for machine and user
authentication (TLS) worked when the user had already logged in
and performed authentication through a desktop utility.
However, it fails "sometimes" when run in a service on boot up.
In the code below why does getCryptProv fail sometimes with error
key set does not exist. What is a workaround for that?
I tried CryptAcquireContext with CRYPT_NEWKEYSET flag if
it failed with NTE_BAD_KEYSET. That did not resolve it.
*/
static int loadCertificate( PCRYPT_HASH_BLOB pHash)
{
//....continued.....
DWORD keyFlags = 0;
if (pHash == NULL)
{
DWORD propId = CERT_KEY_PROV_INFO_PROP_ID;
if ( ( pCertContext = CertFindCertificateInStore
( hSystemStoreHandle,
X509_ASN_ENCODING,
0,
CERT_FIND_PROPERTY,
&propId,
pCertContext ) ) == NULL )
{
dbprint("Could not find a certificate with a NULL hash.\n");
res = 0;
goto end;
}
}
else
{
if ( ( pCertContext = CertFindCertificateInStore
( hSystemStoreHandle,
X509_ASN_ENCODING,
0,
CERT_FIND_HASH,
pHash,
pCertContext ) ) == NULL )
{
dbprint("Could not find a certificate with a given hash.\n");
res = 0;
goto end;
}
}
CertGetCertificateContextProperty(pCertContext,
CERT_KEY_PROV_INFO_PROP_ID, NULL, &cbData);
if ((pinfo = (PCRYPT_KEY_PROV_INFO)malloc(cbData)) == NULL)
{
res = 0;
goto end;
}
if (!CertGetCertificateContextProperty(pCertContext,
CERT_KEY_PROV_INFO_PROP_ID,
pinfo, &cbData))
{
dbprint("Error in CertGetCertificateContextProperty (%x)\n",
GetLastError());
res = 0;
goto end;
}
cert = ms2opensslX509(pCertContext->pbCertEncoded,
pCertContext->cbCertEncoded);
if (SSL_use_certificate(con, cert) != 1)
{
dbprint("Error in SSL_use_certificate\n");
res = 0;
goto end;
}
if ( global.machineKeyset )
{
keyFlags |= CRYPT_MACHINE_KEYSET;
}
key = ms2opensslRSANoPrivateKey(pinfo, keyFlags);
if (key == NULL) {
res = 0;
dbprint( "ms2opensslRSANoPrivateKey did not return a key\n" );
goto end;
}
//....continued.....
}
RSA *ms2opensslRSANoPrivateKey(PCRYPT_KEY_PROV_INFO pinfo, int flags)
{
//....continued.....
MSKeyContext *ctx;
if ((ctx = malloc(sizeof(MSKeyContext))) == NULL)
{
goto err;
}
if ((ctx->hCryptProv = getCryptProv(pinfo, flags)) == 0)
{
//!!!!!!!!!!!!!!! FAILS SOMETIMES WHY??!!!!!!!!!!!!!!//
// Error message is that a keyset does not exist //
// Why can it not find it? //
goto err;
}
//....continued.....
}
static HCRYPTPROV getCryptProv(PCRYPT_KEY_PROV_INFO pinfo, int flags)
{
HCRYPTPROV hProv = 0;
if(!CryptAcquireContext(
&hProv,
pinfo->pwszContainerName,
NULL,
pinfo->dwProvType,
flags))
{
//dbprint( "CrypAcquireContext failed\n" );
}
return hProv;
}
--
Yasir Ali
Software Engineer
Meetinghouse Data Communications
Post by sachin
I am running the following code on XP machines. On some of the machines it
gives error 8009000F at the place that I have marked in the code ###. Error
description says "Object already exists." When does this error occur?
LPCSTR UserName = "MyName";
if (RCRYPT_FAILED(CryptAcquireContext(&hCryptProv, UserName,
MS_ENHANCED_PROV, PROV_RSA_FULL, 0) ) ){
if(GetLastError() == NTE_BAD_KEYSET){
if (RCRYPT_FAILED(CryptAcquireContext(&hCryptProv, UserName,
MS_ENHANCED_PROV,
PROV_RSA_FULL, CRYPT_NEWKEYSET) ) ){
printf("Could not get crypto context
%x",GetLastError() );
Post by sachin
#############ERROR###########
}
else{
return TRUE;
}
}
}
else{
return TRUE;
}
return FALSE;
Thanks,
Sachin
Yasir Ali
2004-08-04 19:09:03 UTC
Permalink
Thanks for your response. I have been doing more investigation on this issue.
After getting NTE_BAD_KEYSET, I was able to generate a NEW KEY SET.
However when I tried to fetch the public key, It gave me an error and did not return the key. It seems that the container created was empty.

As I stated earlier, the issue that I am trying to resolve is to do a TLS authentication on bootup (before windows log on) using a service.

What steps do I need to take to ensure that I have access to the correct key containers in that service?

regards,
Yasir
--
Yasir Ali
Software Engineer
Meetinghouse Data Communications
Post by Ryan Menezes [MSFT]
If you are using CryptAcquireContext in side a service and impersonating a
user, ensure that the user profile is loaded with LoadUserProfile.
If you get a combination of NTE_BAD_KEYSET and NTE_KEY_EXISTS for 0 and
CRYPT_NEWKEYSET with machine keys, it normally indicates you dont have the
correct ACLs on the key containers.
--
Thanks,
Ryan Menezes [MS]
This posting is provided "AS IS" with no warranties, and confers no rights.
Ryan Menezes [MSFT]
2004-09-15 05:43:04 UTC
Permalink
You need to either generate a key pair using CryptGenKey or import it using
CryptImportKey. The container created by CryptAcquireContainer is empty.
--
Thanks,
Ryan Menezes [MS]
This posting is provided "AS IS" with no warranties, and confers no rights.
Post by Yasir Ali
Thanks for your response. I have been doing more investigation on this issue.
After getting NTE_BAD_KEYSET, I was able to generate a NEW KEY SET.
However when I tried to fetch the public key, It gave me an error and did
not return the key. It seems that the container created was empty.
Post by Yasir Ali
As I stated earlier, the issue that I am trying to resolve is to do a TLS
authentication on bootup (before windows log on) using a service.
Post by Yasir Ali
What steps do I need to take to ensure that I have access to the correct
key containers in that service?
Post by Yasir Ali
regards,
Yasir
--
Yasir Ali
Software Engineer
Meetinghouse Data Communications
Post by Ryan Menezes [MSFT]
If you are using CryptAcquireContext in side a service and impersonating a
user, ensure that the user profile is loaded with LoadUserProfile.
If you get a combination of NTE_BAD_KEYSET and NTE_KEY_EXISTS for 0 and
CRYPT_NEWKEYSET with machine keys, it normally indicates you dont have the
correct ACLs on the key containers.
--
Thanks,
Ryan Menezes [MS]
This posting is provided "AS IS" with no warranties, and confers no rights.
v***@gmail.com
2016-11-14 07:43:29 UTC
Permalink
Hello,

I'm also getting the same error. I knew the problem is because of doesn't have correct ASL or could not read key.

Can I know which kind of access you are talking about. Is it simply admin rights or any other Access require.

Kindly help me

danc
2004-08-16 19:49:08 UTC
Permalink
My experience suggests that this happens if the user changes their password
and the old password is not properly saved by the system. This can happen
under the following circumstances:

1. Admin changes the user's password
2. XP client w/t NT 4 server
3. XP client w/t Novel server that has not been updated to latest client
Post by sachin
I am running the following code on XP machines. On some of the machines it
gives error 8009000F at the place that I have marked in the code ###. Error
description says "Object already exists." When does this error occur?
LPCSTR UserName = "MyName";
if (RCRYPT_FAILED(CryptAcquireContext(&hCryptProv, UserName,
MS_ENHANCED_PROV, PROV_RSA_FULL, 0) ) ){
if(GetLastError() == NTE_BAD_KEYSET){
if (RCRYPT_FAILED(CryptAcquireContext(&hCryptProv, UserName,
MS_ENHANCED_PROV,
PROV_RSA_FULL, CRYPT_NEWKEYSET) ) ){
printf("Could not get crypto context %x",GetLastError() );
#############ERROR###########
}
else{
return TRUE;
}
}
}
else{
return TRUE;
}
return FALSE;
Thanks,
Sachin
Loading...