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.
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);
>
>
> .
>
>
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.]
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...
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.
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...
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?
--
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...
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?
--
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...
"John Banes [MS]" <jba...@online.microsoft.com> wrote in message news:<OLNbiX8aCHA.3960@tkmsftngp08>...
"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.
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.