|
|
|
date: Wed, 18 Jun 2008 17:26:24 +0200,
group: microsoft.public.platformsdk.security
back
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
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
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
|
|