Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Error using CryptAcquireCertificatePrivateKey

763 views
Skip to first unread message

Ross Kirk

unread,
Aug 15, 2003, 11:43:29 AM8/15/03
to
Hi,

I have a problem calling CryptAcquireCertificatePrivateKey(). I am
using imported PKS#12 files within the store. The code I have works as
expected for a normal user using the "My" store, however when my code is
run as LocalSystem using the "SMIMESecurity\My" store (this particular
services store) the call to CryptAcquireCertificatePrivateKey() fails
with CRYPT_E_NO_KEY_PROPERTY which suggests that the certificate does
not have a private key.
Viewing the imported certificate via the MMC snap-ins the certificate
says it does have a private key associated with it.
THe problem is that I need this to work under localsystem user. My
current guess is that while I can access the certificate maybe I do not
have the prviliages to access its private key.

Any suggestions gratefully received.

Some a snippet of the code I am trying to get working which should show
you what I am doing

// Get handle to the default provider.
if(!CryptAcquireContext(
&m_hCryptProv,
pszContainer/*NULL*/,
MS_ENHANCED_PROV,
PROV_RSA_FULL,
0))
{
if(!CryptAcquireContext(
&m_hCryptProv,
pszContainer/*NULL*/,
MS_ENHANCED_PROV,
PROV_RSA_FULL,
CRYPT_NEWKEYSET)) // ATTEMPT to generate a default container.
{
SME_THROW(GetLastError(), "Error during CryptAcquireContext!",
NULL);
}
}

if ( ( m_hStoreHandle = CertOpenStore (CERT_STORE_PROV_SYSTEM,
0,
m_hCryptProv,
CERT_SYSTEM_STORE_SERVICES | CERT_STORE_OPEN_EXISTING_FLAG,
L"SMIMESecurity\My" ) ) == NULL )
{
//Error handling here
}

bool bUseThisCert = false;

do {
pTMPSignerCertContext =
CertEnumCertificatesInStore(m_hStoreHandle, pTMPSignerCertContext);

// snip code that works out if the current certificate is the
one selected
if (strstr(pszNameString, lpszCertSubjectName) != NULL) // THIS is
our cert...
bUseThisCert = true;

if (bUseThisCert)
{
DWORD dwKeySpec;
if (bSigner) dwKeySpec=AT_SIGNATURE;
else dwKeySpec=AT_KEYEXCHANGE;

HCRYPTPROV hTmpCryptProv;
BOOL bfCallerFreeProv;
if (!CryptAcquireCertificatePrivateKey(pTMPSignerCertContext,
CRYPT_ACQUIRE_COMPARE_KEY_FLAG, // WE SEEK this exact entry,
// not just the DN
// (careful, we are not yet checking
// KeyUsage here, so maybe encrypt).
NULL, &hTmpCryptProv, &dwKeySpec, &bfCallerFreeProv))
{ // ONLY if it failed above, we will attemp to
// reverse signer/encrypter.
if (GetLastError() == NTE_BAD_PUBLIC_KEY)
{
bUseThisCert = false; // CONTINUE LOOKING.
}
else
{
// CryptAcquireCertificatePrivateKey() fails with
CRYPT_E_NO_KEY_PROPERTY error so we throw this exception
SME_THROW(GetLastError(), "Bad CryptAcquireCertificatePrivateKey(...)
call.", NULL);
} //END IF NTE_BAD_PUBLIC_KEY.
} // END if CryptAcquireCertificatePrivateKey(...)
} while ( !bUseThisCert )

Thanks

Ross

--
Ross Kirk
Software Engineer
Nexor
Tel: +44 (0) 115 952 0500
Fax: +44 (0) 115 952 0519
Mailto: ross...@nexor.com
http://www.nexor.com

Nexor is recognised as an Investor in People and is accredited to ISO
9001/TickIT and IS BS7799. Further details of Nexor's accreditations
can be found on our website.

DISCLAIMER: Privileged or confidential information may be contained in
this message or within any files transmitted with it. If you are not
the intended recipient, kindly destroy the message and notify the sender
by reply email. Opinions, conclusions and other information in this
message that do not relate to the official business of Nexor are
neither given nor endorsed by it.

Sergio Dutra [MS]

unread,
Aug 15, 2003, 12:01:29 PM8/15/03
to
If the service running as LocalSystem, was the key generated also under the
LocalSystem account? If not, the service won't have access to it.

However, the CRYPT_E_NO_KEY_PROPERTY should be returned only when the
CRYPT_KEY_PROV_INFO property is missing on the certificate in question. Make
sure that the certificate being picked is the one that is being viewed in
MMC. It's possible that the certificate being picked by the program does not
have a CRYPT_KEY_PROV_INFO property.

--
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
"Ross Kirk" <ross...@nexor.co.uk> wrote in message
news:eaYWPQ0Y...@TK2MSFTNGP09.phx.gbl...

Ross Kirk

unread,
Aug 18, 2003, 5:37:38 AM8/18/03
to
Sergio Dutra [MS] wrote:

> If the service running as LocalSystem, was the key generated also under the
> LocalSystem account? If not, the service won't have access to it.
>
> However, the CRYPT_E_NO_KEY_PROPERTY should be returned only when the
> CRYPT_KEY_PROV_INFO property is missing on the certificate in question. Make
> sure that the certificate being picked is the one that is being viewed in
> MMC. It's possible that the certificate being picked by the program does not
> have a CRYPT_KEY_PROV_INFO property.
>

I got the certificate into the service store by importing it into the
current users personal store and then copy and pasting the certificate
the the services store.
If I view the certificate with a different user (one that does not also
have the certificate in their personal store) I get a message "Windows
does not have enough information to verify this certificate", although
it also claims there is a private key associated with the certificate.

Is this the wrong way to get the certificate to the service store ?

Sergio Dutra [MS]

unread,
Aug 18, 2003, 11:53:53 AM8/18/03
to
Did you install the issuer of the certificate in the current user's root
store? If so, that would explain why one user would see a full chain, and
the second user would see the error below ("...does not have enough
information...") which means it's a partial (not terminating in a root)
chain.

Also, if you imported the certificate (and private key, I assume) into the
current users personal store, then the key will be ACL'd for the user that
imported it. Copying and pasting the certificate into the service store does
not re-ACL the key for the service. You need to import the certificate and
private key using the user that will actually access the key.

The private key indicator is simply a property on the certificate which
indicates where the private key may be found. However, if the private key
does not exist on the system, the property is not updated to reflect this.

--
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
"Ross Kirk" <ross...@nexor.co.uk> wrote in message

news:eUnsyxWZ...@TK2MSFTNGP10.phx.gbl...

Ross Kirk

unread,
Aug 18, 2003, 1:40:14 PM8/18/03
to
Sergio Dutra [MS] wrote:

> Did you install the issuer of the certificate in the current user's root
> store? If so, that would explain why one user would see a full chain, and

<snip>
Yes, well that explains that one.

> Also, if you imported the certificate (and private key, I assume) into the
> current users personal store, then the key will be ACL'd for the user that
> imported it. Copying and pasting the certificate into the service store does
> not re-ACL the key for the service. You need to import the certificate and
> private key using the user that will actually access the key.

Okay, as my intended user is LocalSystem and AFAIK I cannot login as
LocalSystem how do you suggest I import the certificates ?

Sergio Dutra [MS]

unread,
Aug 18, 2003, 1:46:46 PM8/18/03
to
Have an interface to your service that takes in the certificate/private key
to import, and some UI or cmd-line utility to access that interface.

--
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
"Ross Kirk" <ross...@nexor.co.uk> wrote in message

news:ec%23Ye$aZDHA...@TK2MSFTNGP10.phx.gbl...

Ross Kirk

unread,
Aug 26, 2003, 12:23:04 PM8/26/03
to
Sergio Dutra [MS] wrote:

> Have an interface to your service that takes in the certificate/private key
> to import, and some UI or cmd-line utility to access that interface.
>

I seem to be getting somewhere now :)

I have used the 'cmdasuser'
(http://www.develop.com/kbrown/security/sample_cmdasuser.htm) to allow
me to import the certificates as the localsystem user. My application
can now find the certificates and works fine with them.

My question now is, is this a valid method of importing the certificates
to the localsystem store? (ie using a program I supply)
Or is it possible to use the Crypt API to import the certificate to
LocalSystem store (as a different user who is running the application)
and have the certificate valid for use by the LocalSystem user?

Thanks for all your help.

Sergio Dutra [MS]

unread,
Sep 2, 2003, 12:15:40 PM9/2/03
to
You can use CryptoAPI to import the certificate into the LocalMachine store
as any user. However, if you're importing a PFX, which includes the private
key, and you want that private key to be accessible by a particular account,
then the PFX must be imported by that particular account (in this case,
LOCAL SYSTEM).

--
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
"Ross Kirk" <ross...@nexor.co.uk> wrote in message

news:ug$xp5%23aDH...@TK2MSFTNGP12.phx.gbl...

0 new messages