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

AcquireCredentialsHandle

268 views
Skip to first unread message

Alun Jones

unread,
Oct 3, 2002, 12:27:26 PM10/3/02
to
In article <446601c26a86$6bd29540$35ef2ecf@TKMSFTNGXA11>, "Ichsan"
<ichsa...@softhome.net> wrote:
>Anyone,please help me with this problem.
>
>I need to use this function to create SSL communication
>between server and
>client. If there is any other suggestion or link, I will
>try it.

I find that certificates created in OpenSSL using DSA for the signature don't
work with AcquireCredentialsHandle. I'm still working on trying to find out
from Microsoft exactly why. Noone seems to be able to answer the question.
If you search in Google, you'll see this question's been asked two or three
times here, to a complete silence from Microsoft.

Alun.
~~~~

[Please don't email posters, if a Usenet response is appropriate.]
--
Texas Imperial Software | Try WFTPD, the Windows FTP Server. Find us at
1602 Harvest Moon Place | http://www.wftpd.com or email al...@texis.com
Cedar Park TX 78613-1419 | VISA/MC accepted. NT-based sites, be sure to
Fax/Voice +1(512)258-9858 | read details of WFTPD Pro for XP/2000/NT.

John Banes [MS]

unread,
Oct 3, 2002, 9:30:36 PM10/3/02
to
The most common reason for this is that the private key corresponding to the
certificate is stored in the wrong CSP. Because the CSP is required to
support a number of SSL-specific key derivation algorithms when performing
server-side SSL handshakes, all server private keys need to be stored in
CSPs of type PROV_RSA_SCHANNEL or PROV_DH_SCHANNEL. If a PROV_RSA_SCHANNEL
CSP is used, then the key needs to be of type AT_KEYEXCHANGE.

If this is the case, then you can either reenroll for the server certificate
(and choose a different CSP this time), or you can programatically modify
the "key provider info" property that's on the server certificate in the
certificate store. Note that this latter method only works when switching
keys between Microsoft CSPs, and only when moving the CSP type from:

PROV_RSA_FULL <---> PROV_RSA_SCHANNEL
PROV_RSA_SIGNATURE <---> PROV_RSA_SCHANNEL

PROV_DSS <---> PROV_DH_SCHANNEL

--
Regards,

John Banes
[Microsoft Security Developer]

This posting is provided "AS IS" with no warranties, and confers no rights.
Please do not send email directly to this alias. This alias is for newsgroup
purposes only.
"Ichsan" <ichsa...@softhome.net> wrote in message
news:446601c26a86$6bd29540$35ef2ecf@TKMSFTNGXA11...


> Anyone,please help me with this problem.
>
> I need to use this function to create SSL communication
> between server and
> client. If there is any other suggestion or link, I will
> try it.
>

> Thanks for advance
>
> "ican" <ichsa...@softhome.net> wrote in message
> news:3e9201c26078$e965cc60$3aef2ecf@TKMSFTNGXA09...
> > Dear all,
> >
> > I have problem with function AcquireCredentialsHandle in
> > serverside.
> > After successfully use CertFindCertificateInStore, i use
> > function AcquireCredentialsHandle but i always get
> > SEC_E_NO_CREDENTIALS error. If i continue to use function
> > AcceptSecurityContext, i get serious error.
> > Why is this happen?
> >
> > Thank you very much
> >
> > ZeroMemory(&m_SchannelCred, sizeof m_SchannelCred));
> > m_SchannelCred.dwVersion =SCHANNEL_CRED_VERSION;
> > m_SchannelCred.cCreds = 1;
> > m_SchannelCred.paCred = &m_pCertContext;
> > m_SchannelCred.grbitEnabledProtocols = SP_PROT_SSL3;
> >
> > AcquireCredentialsHandle(
> > NULL,
> > UNISP_NAME_A,
> > SECPKG_CRED_INBOUND,
> > NULL,
> > &m_SchannelCred,
> > NULL,
> > NULL,
> > phCreds,
> > &tsExpiry);
>
>
> .
>
>


Alun Jones

unread,
Oct 4, 2002, 10:11:23 AM10/4/02
to
In article <uMCy6V0aCHA.1668@tkmsftngp09>, "John Banes [MS]"
<jba...@online.microsoft.com> wrote:
>If this is the case, then you can either reenroll for the server certificate
>(and choose a different CSP this time), or you can programatically modify
>the "key provider info" property that's on the server certificate in the
>certificate store. Note that this latter method only works when switching
>keys between Microsoft CSPs, and only when moving the CSP type from:

Let's assume (as in my case) that the server certificate was requested from,
and issued by, an OpenSSL system, not a Windows 2000 Certificate Server.
OpenSSL presumably knows squat about Microsoft CSPs, and I doubt that they
include a Microsoft CSP specification in their certificate export formats.
So, how does one modify that "key provider info" to choose a different CSP?
Indeed, how does one even verify whether that is the cause of the problem?

>PROV_RSA_FULL <---> PROV_RSA_SCHANNEL
>PROV_RSA_SIGNATURE <---> PROV_RSA_SCHANNEL
>
>PROV_DSS <---> PROV_DH_SCHANNEL

How do you do this? What tool do you use to analyse the certificate to
determine that this is the case? What tools are available for certificate
analysis and debugging? Please assume that there are some of us who are
capable of understanding these things if we're provided with tools and
documentation. The documentation is pretty thin on the ground, as is source
code, tools or examples. You're the only name that I see on all the samples
and documentation that I can make use of, so I am starting from the assumption
that you're the best person to contact about this. [One of the MCSE Windows
2000 course books actually states that "Alice encrypts her message with Bob's
private key". Yeesh.]

John Banes [MS]

unread,
Oct 4, 2002, 12:49:38 PM10/4/02
to
I'm not really an authority when it comes to certificate enrollment, but our
usage model seems to assume that users will enroll for the certificate on
the machine that's going to use the certificate. Creating the certificate
elsewhere and importing it is a bit of a fringe case. However, here are some
general guidelines.

All of the Microsoft software CSPs currently store their private keys in
exactly the same format, and so it's possible to change the CSP ownership of
the private key without breaking them. I don't know if things will always be
this way, but that's the current situation. Some CSP support RSA keys and
some support DH and DSS keys, and you can't switch between these.

Certificates that are stored in the "personal" certificate store or "MY" (as
it's referred to programmatically) have a property on them (KeyProvInfo)
that points to the CSP that owns the private key. All server certificates
should point to an "schannel" CSP if you hope to use them for server-side
SSL.

You can view this property using the certutil.exe utility. This is shipped
bundled with the Microsoft certificate server, and it might be available
separately as well. This utility does many many things, but here's a couple
of commands to get you started.

To list the certificates in your machine MY certificate store:

certutil -store my

If you notice that one of your server certificates isn't stored in an
schannel CSP, you can replace the KeyProvInfo property using a command
something like this:

certutil -csp "Microsoft RSA SChannel Cryptographic Provider"
-f -repairstore my 14ddd265000000004a88

The "14ddd265000000004a88" parameter is the serial number of the certificate
that you want to modify.

So in summary, you should be able to import a server PFX file that was
generated using OpenSSL or some other tool, and then change the CSP that's
used to the appropriate schannel one. With any luck, that is...

--
Regards,

John Banes
[Microsoft Security Developer]

This posting is provided "AS IS" with no warranties, and confers no rights.
Please do not send email directly to this alias. This alias is for newsgroup
purposes only.

"Alun Jones" <al...@texis.com> wrote in message
news:fkhn9.1087$NX7.21...@newssvr11.news.prodigy.com...

Alun Jones

unread,
Oct 4, 2002, 3:22:04 PM10/4/02
to
In article <OLNbiX8aCHA.3960@tkmsftngp08>, "John Banes [MS]"
<jba...@online.microsoft.com> wrote:
>I'm not really an authority when it comes to certificate enrollment, but our
>usage model seems to assume that users will enroll for the certificate on
>the machine that's going to use the certificate. Creating the certificate
>elsewhere and importing it is a bit of a fringe case. However, here are some
>general guidelines.

Let's assume for the moment that we're running on a system with no Windows
2000 servers, or with none that local policies will let us turn into a
Certificate Server. Enrollment then may require generation of certificates by
a system other than Microsoft's. For what it's worth, my tests to date have
been using XP - standalone - for creating and importing the certificate.
Since XP doesn't have a certificate authority package, this has to be done
with a third-party tool such as OpenSSL, and the final certificate imported
using a PFX file.

>All of the Microsoft software CSPs currently store their private keys in
>exactly the same format, and so it's possible to change the CSP ownership of
>the private key without breaking them. I don't know if things will always be
>this way, but that's the current situation. Some CSP support RSA keys and
>some support DH and DSS keys, and you can't switch between these.

That's a bit of an ouch - it would be very helpful if we could have a
'sanctified' method of verifying that a certificate is suited for SChannel,
and of making it suitable for SChannel if it is not currently suited.

>Certificates that are stored in the "personal" certificate store or "MY" (as
>it's referred to programmatically) have a property on them (KeyProvInfo)
>that points to the CSP that owns the private key. All server certificates
>should point to an "schannel" CSP if you hope to use them for server-side
>SSL.

Hmm... Since we're in microsoft.public.PlatformSDK.security, I was hoping for
a bit more of an API-style way of doing this, but your information was enough
to send me hopping through the MSDN Library... Here's my code - assume that
we start with "pContext" as a PCCERT_CONTEXT, and that GetCredHandle() is my
function that takes a PCCERT_CONTEXT, returning SEC_E_OK if we could
successfully call AcquireCredentialsHandle on that context.

The code is probably sub-optimal - I'm particularly concerned that I'm setting
the provider type _and_ the provider name (setting the type alone didn't do
the trick). Perhaps others can spot my errors? There's essentially no error
handling - I was single stepping through, checking the value of bRv.

tryagain:
if (SEC_E_OK!=GetCredHandle(pContext))
{
// Unable to call AcquireContextHandle - maybe it's not SCHANNEL?
DWORD dwProvSize=0;
BOOL bRv = CertGetCertificateContextProperty( pContext,
CERT_KEY_PROV_INFO_PROP_ID, NULL, &dwProvSize);
if (bRv)
{
CRYPT_KEY_PROV_INFO *pProvInfo=(CRYPT_KEY_PROV_INFO *)
new char[dwProvSize];
bRv = CertGetCertificateContextProperty( pContext,
CERT_KEY_PROV_INFO_PROP_ID, pProvInfo, &dwProvSize);
if (PROV_DSS_DH==pProvInfo->dwProvType)
{
pProvInfo->dwProvType=PROV_DH_SCHANNEL;
pProvInfo->pwszProvName=MS_DEF_DH_SCHANNEL_PROV_W;
bRv = CertSetCertificateContextProperty( pContext,
CERT_KEY_PROV_INFO_PROP_ID, 0, (void *)pProvInfo);
bRv = CertGetCertificateContextProperty( pContext,
CERT_KEY_PROV_INFO_PROP_ID, pProvInfo, &dwProvSize);
delete [] (char *)pProvInfo;
goto tryagain;
}
delete [] (char *)pProvInfo;
}
AfxMessageBox("Unable to acquire context handle - "
"this certificate might not work.");
}

Apologies if any wrapping makes this unreadable or unworkable.

John Banes [MS]

unread,
Oct 4, 2002, 4:51:12 PM10/4/02
to
This code looks okay, mostly. Setting both the CSP name and type is indeed
necessary.

When you check to see if the CSP type is PROV_DSS_DH, you should probably
also check to see if the CSP name is one of the Microsoft DSS/DH CSPs. That
way, you won't accidently whack a private key that belongs to a third-party
CSP.

--
Regards,

John Banes
[Microsoft Security Developer]

This posting is provided "AS IS" with no warranties, and confers no rights.
Please do not send email directly to this alias. This alias is for newsgroup
purposes only.
"Alun Jones" <al...@texis.com> wrote in message

news:wTln9.63$V45.13...@newssvr30.news.prodigy.com...

Alun Jones

unread,
Oct 4, 2002, 7:41:24 PM10/4/02
to
In article <##Ilbe#aCHA.460@tkmsftngp08>, "John Banes [MS]"
<jba...@online.microsoft.com> wrote:
>This code looks okay, mostly. Setting both the CSP name and type is indeed
>necessary.
>
>When you check to see if the CSP type is PROV_DSS_DH, you should probably
>also check to see if the CSP name is one of the Microsoft DSS/DH CSPs. That
>way, you won't accidently whack a private key that belongs to a third-party
>CSP.

For my purposes I don't know that this is necessary - this is in a piece of
code that selects a certificate for use in an SSL / TLS transaction over
SChannel. If the type doesn't support SChannel, then it isn't going to work
for me, third-party or not. Or am I wrong?

John Banes [MS]

unread,
Oct 4, 2002, 11:13:33 PM10/4/02
to
Well, I'm thinking that maybe such a certificate could there for some other
purpose. If you're sure that the certificate in question is intended for use
as an SSL server certificate and nothing else, then it probably doesn't
matter. :-)

--
Regards,

John Banes
[Microsoft Security Developer]

This posting is provided "AS IS" with no warranties, and confers no rights.
Please do not send email directly to this alias. This alias is for newsgroup
purposes only.
"Alun Jones" <al...@texis.com> wrote in message

news:EGpn9.642$AW.178...@newssvr12.news.prodigy.com...

Alun Jones

unread,
Oct 7, 2002, 6:40:27 AM10/7/02
to
In article <#SZ7H0BbCHA.1292@tkmsftngp12>, "John Banes [MS]"
<jba...@online.microsoft.com> wrote:
>Well, I'm thinking that maybe such a certificate could there for some other
>purpose. If you're sure that the certificate in question is intended for use
>as an SSL server certificate and nothing else, then it probably doesn't
>matter. :-)

Okay, this is going to sound really stupid, but for what purpose would such a
certificate be used, that couldn't be satisfied by the SCHANNEL CSP?

John Banes [MS]

unread,
Oct 7, 2002, 8:06:28 PM10/7/02
to
IPSEC, for example.

--
Regards,

John Banes
[Microsoft Security Developer]

This posting is provided "AS IS" with no warranties, and confers no rights.
Please do not send email directly to this alias. This alias is for newsgroup
purposes only.
"Alun Jones" <al...@texis.com> wrote in message

news:vwdo9.748$xY.329...@newssvr30.news.prodigy.com...

Alex Huang

unread,
Oct 30, 2002, 12:50:37 PM10/30/02
to
Here is all I get from certutil.exe dated dec, 1999:
================ Certificate 3 ================
X509 Certificate:
Subject:
CN=TEST1
OU=engineering
O=mycom
L=la
S=ca
C=US
E=ale...@ix.netcom.com
Signature matches Public Key
Root Certificate: Subject matches Issuer
Cert Hash(md5): 8d c3 db 0d a9 a0 c6 2a 9d 73 e2 ae 10 5a 97 f7
Cert Hash(sha1): 63 d3 6b 14 cc b4 e3 a3 0e 17 2b 0a 50 32 ea 93 58 a2
dd ca
Key Container = TEST1
Found matching key
================
I don't see the CSP (KeyProvInfo) information. In addition,
-repairstore is not a valid option. Is there a newer version of
certutil.exe somewhere? Is there another way to make sure that the
failure of AcquireCredentialHandle is not caused by the misplacement
of the key in the wrong CSP? Thanks a lot for your information in
advance!


"John Banes [MS]" <jba...@online.microsoft.com> wrote in message news:<OLNbiX8aCHA.3960@tkmsftngp08>...

Alex Huang

unread,
Oct 31, 2002, 3:04:33 PM10/31/02
to
I am confused. A certificate has no private key in it. The key pair is
stored in the CSP's key container. You can't just change the CSP type
and name of the certificate. You also need to move the key pair from
the wrong CSP to the right one, right?! If that is the case, does
anybody know of such a tool that moves keys between CSPs?

"John Banes [MS]" <jba...@online.microsoft.com> wrote in message news:<##Ilbe#aCHA.460@tkmsftngp08>...


> This code looks okay, mostly. Setting both the CSP name and type is indeed
> necessary.
>
> When you check to see if the CSP type is PROV_DSS_DH, you should probably
> also check to see if the CSP name is one of the Microsoft DSS/DH CSPs. That
> way, you won't accidently whack a private key that belongs to a third-party
> CSP.

Alun Jones

unread,
Oct 31, 2002, 5:45:10 PM10/31/02
to
In article <7274c054.02103...@posting.google.com>,
ale...@ix.netcom.com (Alex Huang) wrote:
>I am confused. A certificate has no private key in it. The key pair is
>stored in the CSP's key container. You can't just change the CSP type
>and name of the certificate. You also need to move the key pair from
>the wrong CSP to the right one, right?! If that is the case, does
>anybody know of such a tool that moves keys between CSPs?

The language in some of this discussion is a little loose, as in most
discussions of certificates. Usually the term "certificate" is used to
describe "certificate and anything else we store with it". Usually
"certificate" at least means "certificate, signature, and public key" - as in
"the server exchanges certificates with the client" - it'd be no use for
either one to tell the other about only the name and other information that
makes up the certificate, so it's taken as given that the "certificate"
exchange carries other information.

In this case, we're not moving a "certificate" from one CSP to another. We're
actually moving a certificate _context_ from one CSP to the other - the whole
thing, including private keys if we have them. The code I provided will do
what you need, if you need something in source code form. You'll obviously
have to provide a little more code around it.

Alex Huang

unread,
Nov 7, 2002, 11:30:48 AM11/7/02
to
Alun, Thanks a lot for your help!
0 new messages