Ureader.com  
Microsoft software help and Community
   home   |   control panel login   |   archive   |  
 
platform
active.directory
adsi
adsi.iis-admin
base
com_ole
complus_mts
component_svcs
database
directx
gdi
graphics_mm
internet.client
internet.server
internet.server.isapi-dev
localization
mapi
messaging
msi
mslayerforunicode
multimedia
networking
networking.ipv6
sdk_install
security
shell
telephony.tapi_2
telephony.tapi_3
telephony.tsp
telephony.wte
tools
ui
ui_shell
win_base_svcs
win16
  
 
date: Wed, 18 Jun 2008 17:26:24 +0200,    group: microsoft.public.platformsdk.security        back       


Acquiring private key   
Hello,

I am trying to get a HCRYPTPROV from a certificate private key stored in 
a smart card. I am using CryptAcquireCertificatePrivateKey(). It works 
with an application launched by the user, but it fails when called from 
an application running as system.

Is there another way to get this handle ? I tried with 
CertGetCertificateContextProperty (), but it failed also.

Thanks.

Regards.

Eric Boudrand
date: Wed, 18 Jun 2008 17:26:24 +0200   author:   Eric Boudrand

RE: Acquiring private key   
Hi Eric,

How did you get the PCCERT_CONTEXT parameter you are using in these 
functions? Is it from the certificate store of the user or the LocalSystem 
one?
Usually, smart card vendor ships with there software a program that will 
lunch when the user logs on and that scans the inserted smart cards, loading 
there certificates to the user "MY" certificate store. So, in this case, the 
certificate context and its private key are only accessible to this user.
If you want to access the private key of a smart card from a service, you 
can proceed like Winlogon does : you call CryptAcquireContext on the desired 
smart card reader (using "\\.\Your Reader Name\" as a container name), then 
enumerate all the containers in order to choose the one that contains the 
desired certificate. Once found, you can get the handle of its key using 
CryptGetUserKey as usual.

Cheers,
-- 
Mounir IDRASSI
IDRIX
http://www.idrix.fr

to reach : mounir_idrix_fr (replace the underscores with the at and dot 
characters respectively)


"Eric Boudrand" wrote:

> Hello,
> 
> I am trying to get a HCRYPTPROV from a certificate private key stored in 
> a smart card. I am using CryptAcquireCertificatePrivateKey(). It works 
> with an application launched by the user, but it fails when called from 
> an application running as system.
> 
> Is there another way to get this handle ? I tried with 
> CertGetCertificateContextProperty (), but it failed also.
> 
> Thanks.
> 
> Regards.
> 
> Eric Boudrand
>
date: Wed, 18 Jun 2008 10:43:03 -0700   author:   Mounir IDRASSI am

Re: Acquiring private key   
Hello Mounir,

Thank you for your answer.

 > If you want to access the private key of a smart card from a service,
 > you can proceed like Winlogon does : you call CryptAcquireContext on
 > the desired smart card reader (using "\\.\Your Reader Name\" as a
 > container name), then enumerate all the containers in order to choose
 > the one that contains the desired certificate. Once found, you can get
 > the handle of its key using CryptGetUserKey as usual.

It is almost what I am doing.

I call CryptAcquireContext() on the smart card reader name as container 
and on the CSP (Microsoft Base Smart Card Crypto Provider)
Then I am calling directly CryptGetUserKey() and I got a HCRYPTKEY. I am 
not enumerating the containers. In my testing there is only one 
certificate on the smart card. I will implement it later.

But, I need a HCRYPTPROV because I want to call CryptCreateHash(). My 
goal is to call CryptSignHash(). That is the reason why I am calling 
CryptAcquireCertificatePrivateKey().

Once I got a HCRYPTKEY, I call CryptGetKeyParam(dwParam=KP_CERTIFICATE) 
twice in order to retrieve the certificate. Then I call 
CertCreateCertificateContext() for PCCERT_CONTEXT, that I use with 
CryptAcquireCertificatePrivateKey().

I find this sequence complicated. But, I have no idea for simplying it.

Regards.

Eric Boudrand
date: Thu, 19 Jun 2008 13:04:30 +0200   author:   Eric Boudrand

Re: Acquiring private key   
Hi Eric,

What you don't simply use HCRYPTPROV you get from the first 
CryptAcquireContext?
Since it's the handle to the container containing your key, all the calls of 
CAPI signature functions will work. There is no need to have another 
dedicated HCRYPTPROV. For example, Winlogon do the same: he calls 
CryptAcquireContext, then CryptGetUserKey, then retrieves the certificate 
using CryptGetKeyParam, then performs the signature operations using the same 
HCRYPTPROV. 

Honestly, I think you can really simplify things.

Cheers,
-- 
Mounir IDRASSI
IDRIX
http://www.idrix.fr

to reach : mounir_idrix_fr (replace the underscores with the at and dot 
characters respectively)


"Eric Boudrand" wrote:

> Hello Mounir,
> 
> Thank you for your answer.
> 
>  > If you want to access the private key of a smart card from a service,
>  > you can proceed like Winlogon does : you call CryptAcquireContext on
>  > the desired smart card reader (using "\\.\Your Reader Name\" as a
>  > container name), then enumerate all the containers in order to choose
>  > the one that contains the desired certificate. Once found, you can get
>  > the handle of its key using CryptGetUserKey as usual.
> 
> It is almost what I am doing.
> 
> I call CryptAcquireContext() on the smart card reader name as container 
> and on the CSP (Microsoft Base Smart Card Crypto Provider)
> Then I am calling directly CryptGetUserKey() and I got a HCRYPTKEY. I am 
> not enumerating the containers. In my testing there is only one 
> certificate on the smart card. I will implement it later.
> 
> But, I need a HCRYPTPROV because I want to call CryptCreateHash(). My 
> goal is to call CryptSignHash(). That is the reason why I am calling 
> CryptAcquireCertificatePrivateKey().
> 
> Once I got a HCRYPTKEY, I call CryptGetKeyParam(dwParam=KP_CERTIFICATE) 
> twice in order to retrieve the certificate. Then I call 
> CertCreateCertificateContext() for PCCERT_CONTEXT, that I use with 
> CryptAcquireCertificatePrivateKey().
> 
> I find this sequence complicated. But, I have no idea for simplying it.
> 
> Regards.
> 
> Eric Boudrand
>
date: Thu, 19 Jun 2008 04:26:01 -0700   author:   Mounir IDRASSI am

Re: Acquiring private key   
Hello,

> What you don't simply use HCRYPTPROV you get from the first
> CryptAcquireContext?
> Since it's the handle to the container containing your key, all the calls of
> CAPI signature functions will work. There is no need to have another
> dedicated HCRYPTPROV. For example, Winlogon do the same: he calls
> CryptAcquireContext, then CryptGetUserKey, then retrieves the certificate
> using CryptGetKeyParam, then performs the signature operations using the same
> HCRYPTPROV.

I did that way first. I am generating a signature and I am sending it
to a remote server using OpenSSL. The remote server is not able to
authenticate the signature (error "Invalid SIG"). I must add that I
reversed the byte order in the signature that I sent. If I do not do
that I have error "RSA_padding_check_PKCS1_type_1:block type is not
01" on the remote server.

For signing, CryptSignHash() is using a private key. My first
hypothesis is : I am not using the appropriate private key. I am
wondering how CryptSignHash can use the good private key if not link
is set to the key pair ? I must have forgotten something.

I have another smart card  with the same certificate that I can access
with PKCS#11 and I have no issue.

Regards.

Eric Boudrand

P.S. : I have problem for reading your posts from my newreaders (from
Linux as from Windows). I do not receive them. That's why I am posting
from Google News.
date: Thu, 19 Jun 2008 05:16:13 -0700 (PDT)   author:   unknown

Re: Acquiring private key   
Hi,

As you know, each CSP container can store two key pairs : one for 
AT_KEYEXCHANGE and one for AT_SIGNATURE. So, if you don't use the right 
dwKeySpec parameter for CryptGetUserKey, the signature verification will 
fail. CryptSignHash rely on the handle returned by CryptGetUserKey to do the 
computation.
If you are sure of your KeySpec and you still can't verify the signature, 
you have to check if the certificate associated with the key (KP_CERTIFICATE) 
is the right one, because maybe there is a bug in the CSP or on the way the 
container is created and populated. 
Anyway, no matter what API you call, at the end you will have calls to 
CryptAcquireContext, CryptGetUserKey and CryptSignHash. These are the most 
low level functions that exist and all the other APIs are based on them.

Cheers,

PS: I post using the MSDN news reader and I use outlook to read the posts 
and all my posts are visible trough Outlook, at least for me.
-- 
Mounir IDRASSI
IDRIX
http://www.idrix.fr

to reach : mounir_idrix_fr (replace the underscores with the at and dot 
characters respectively)


"eric.boudrand@gmail.com" wrote:

> Hello,
> 
> > What you don't simply use HCRYPTPROV you get from the first
> > CryptAcquireContext?
> > Since it's the handle to the container containing your key, all the calls of
> > CAPI signature functions will work. There is no need to have another
> > dedicated HCRYPTPROV. For example, Winlogon do the same: he calls
> > CryptAcquireContext, then CryptGetUserKey, then retrieves the certificate
> > using CryptGetKeyParam, then performs the signature operations using the same
> > HCRYPTPROV.
> 
> I did that way first. I am generating a signature and I am sending it
> to a remote server using OpenSSL. The remote server is not able to
> authenticate the signature (error "Invalid SIG"). I must add that I
> reversed the byte order in the signature that I sent. If I do not do
> that I have error "RSA_padding_check_PKCS1_type_1:block type is not
> 01" on the remote server.
> 
> For signing, CryptSignHash() is using a private key. My first
> hypothesis is : I am not using the appropriate private key. I am
> wondering how CryptSignHash can use the good private key if not link
> is set to the key pair ? I must have forgotten something.
> 
> I have another smart card  with the same certificate that I can access
> with PKCS#11 and I have no issue.
> 
> Regards.
> 
> Eric Boudrand
> 
> P.S. : I have problem for reading your posts from my newreaders (from
> Linux as from Windows). I do not receive them. That's why I am posting
> from Google News.
>
date: Thu, 19 Jun 2008 12:23:01 -0700   author:   Mounir IDRASSI am

Re: Acquiring private key   
Hi,

> As you know, each CSP container can store two key pairs : one for
> AT_KEYEXCHANGE and one for AT_SIGNATURE. So, if you don't use the right
> dwKeySpec parameter for CryptGetUserKey, the signature verification will
> fail. CryptSignHash rely on the handle returned by CryptGetUserKey to do
> the computation.

I noticed a problem in the following sequence :
I call successfully :
CryptGetUserKey(m_hCryptProvider, AT_KEYEXCHANGE, &m_hCryptKey)

Then I call :
CryptGetKeyParam(m_hCryptKey, KP_ALGID,(BYTE*)&algo_id, &len,0)
the value of algo_id is CALG_RSA_KEYX

Then I call
CryptCreateHash(m_hCryptProvider, CALG_RSA_KEYX, m_hCryptKey, NULL,
&m_hCryptHash)
It failed with error NTE_BAD_KEY.

Is the CryptCreateHash call correct ?

> PS: I post using the MSDN news reader and I use outlook to read the posts
> and all my posts are visible trough Outlook, at least for me.

The most surprising is the fact I can read your answers to every posts
expects mine :-(. But, I found the issue. The bug is coming from my ISP. I
was using a Free Telecom news server. I switched to another one. I can
download now your answers from msnews.microsoft.com.

Regards.

Eric Boudrand
date: Fri, 20 Jun 2008 16:05:22 +0200   author:   Eric Boudrand

Re: Acquiring private key   
The second parameter of CryptCreateHash is definitely WRONG. It shall be a 
HASH algo (like CALG_SHA1).

Laszlo Elteto
SafeNet, Inc.

"Eric Boudrand" wrote:

> Hi,
> 
> > As you know, each CSP container can store two key pairs : one for
> > AT_KEYEXCHANGE and one for AT_SIGNATURE. So, if you don't use the right
> > dwKeySpec parameter for CryptGetUserKey, the signature verification will
> > fail. CryptSignHash rely on the handle returned by CryptGetUserKey to do
> > the computation.
> 
> I noticed a problem in the following sequence :
> I call successfully :
> CryptGetUserKey(m_hCryptProvider, AT_KEYEXCHANGE, &m_hCryptKey)
> 
> Then I call :
> CryptGetKeyParam(m_hCryptKey, KP_ALGID,(BYTE*)&algo_id, &len,0)
> the value of algo_id is CALG_RSA_KEYX
> 
> Then I call
> CryptCreateHash(m_hCryptProvider, CALG_RSA_KEYX, m_hCryptKey, NULL,
> &m_hCryptHash)
> It failed with error NTE_BAD_KEY.
> 
> Is the CryptCreateHash call correct ?
> 
> > PS: I post using the MSDN news reader and I use outlook to read the posts
> > and all my posts are visible trough Outlook, at least for me.
> 
> The most surprising is the fact I can read your answers to every posts
> expects mine :-(. But, I found the issue. The bug is coming from my ISP. I
> was using a Free Telecom news server. I switched to another one. I can
> download now your answers from msnews.microsoft.com.
> 
> Regards.
> 
> Eric Boudrand
> 
> 
> 
> 
> 
> 
> 
>
date: Fri, 20 Jun 2008 08:36:01 -0700   author:   lelteto

Re: Acquiring private key   
Hi Eric,

As Laszlo said, you are using a wrong value for the hash Algid. But most 
important, the bug also resides in the fact that you specify m_hCryptKey as 
the hKey parameter of CryptCreateHash where you should only put NULL. 
Actually, This parameter is only used for keyed hash algorithms like HMAC and 
for classical digest algorithms like SHA-1, it should always be NULL.
So, the code should look like this : 
CryptCreateHash(m_hCryptProvider, CALG_SHA1, NULL, NULL, &m_hCryptHash) 

Cheers,
-- 
Mounir IDRASSI
IDRIX
http://www.idrix.fr

to reach : mounir_idrix_fr (replace the underscores with the at and dot 
characters respectively)


"lelteto" wrote:

> The second parameter of CryptCreateHash is definitely WRONG. It shall be a 
> HASH algo (like CALG_SHA1).
> 
> Laszlo Elteto
> SafeNet, Inc.
>
date: Fri, 20 Jun 2008 12:54:00 -0700   author:   Mounir IDRASSI am

Re: Acquiring private key   
Hi,

> The second parameter of CryptCreateHash is definitely WRONG. It shall be a
> HASH algo (like CALG_SHA1).

Thanks.

Eric Boudrand
date: Mon, 23 Jun 2008 10:04:43 +0200   author:   Eric Boudrand

Google
 
Web ureader.com


    COPYRIGHT 2007, YARDI TECHNOLOGY LIMITED, ALL RIGHT RESERVE  |   contact us