Discussion:
Use USB-token client certificate
(too old to reply)
Lingyan
2005-04-02 09:17:01 UTC
Permalink
I am using the SSL sample code (Microsoft
SDK\Samples\security\SSPI\SSL\WebClient) to establish SSL tunnels with a
server. I have been able to use client certificate without any problem until
today I have to try a USB-token. From the trace it looks like I got the
certificate by:
pChainContext = CertFindChainInStore(m_hMyCertStore,
X509_ASN_ENCODING,
0,
CERT_CHAIN_FIND_BY_ISSUER,
&FindByIssuerPara,
pChainContext);

But when I try to call the following function to create the new credential
with the certificate it fails with error code 0x8009030D.
Status = g_pSSPI->AcquireCredentialsHandleA(
NULL, // Name of principal
UNISP_NAME_A, // Name of package
SECPKG_CRED_OUTBOUND, // Flags indicating use
NULL, // Pointer to logon ID
&m_SchannelCred, // Package specific data
NULL, // Pointer to GetKey()
func
NULL, // Value to pass to
GetKey()
&hCreds, // (out) Cred Handle
&tsExpiry); // (out) Lifetime
(optional)

Any thoughts? Thanks!
lelteto
2005-04-03 19:17:03 UTC
Permalink
Did you install the USB token's CSP? Did you check that the provider ID
(CERT_KEY_PROV_HANDLE_PROP_ID) when you call
CertGetCertificateContextProperty points to the USB token's CSP?

Laszlo Elteto
SafeNet, Inc.
Post by Lingyan
I am using the SSL sample code (Microsoft
SDK\Samples\security\SSPI\SSL\WebClient) to establish SSL tunnels with a
server. I have been able to use client certificate without any problem until
today I have to try a USB-token. From the trace it looks like I got the
pChainContext = CertFindChainInStore(m_hMyCertStore,
X509_ASN_ENCODING,
0,
CERT_CHAIN_FIND_BY_ISSUER,
&FindByIssuerPara,
pChainContext);
But when I try to call the following function to create the new credential
with the certificate it fails with error code 0x8009030D.
Status = g_pSSPI->AcquireCredentialsHandleA(
NULL, // Name of principal
UNISP_NAME_A, // Name of package
SECPKG_CRED_OUTBOUND, // Flags indicating use
NULL, // Pointer to logon ID
&m_SchannelCred, // Package specific data
NULL, // Pointer to GetKey()
func
NULL, // Value to pass to
GetKey()
&hCreds, // (out) Cred Handle
&tsExpiry); // (out) Lifetime
(optional)
Any thoughts? Thanks!
Lingyan
2005-04-04 07:05:09 UTC
Permalink
No, I didn't install any CSP and I didn't use
CertGetCertificateContextProperty. The following is the sample code I used. I
thought this should behave the same as IE. IE can use the certificate and
access the server without any problem. In the following code
AcquireCredentialsHandleA returned SEC_E_UNKNOWN_CREDENTIALS.

// Find a certificate chain.
pChainContext = CertFindChainInStore(hMyCertStore,
X509_ASN_ENCODING,
0,
CERT_CHAIN_FIND_BY_ISSUER,
&FindByIssuerPara,
pChainContext);
if(pChainContext == NULL)
{
printf("Error 0x%x finding cert chain\n", GetLastError());
break;
}
printf("\ncertificate chain found\n");

// Get pointer to leaf certificate context.
pCertContext = pChainContext->rgpChain[0]->rgpElement[0]->pCertContext;

// Create schannel credential.
SchannelCred.dwVersion = SCHANNEL_CRED_VERSION;
SchannelCred.cCreds = 1;
SchannelCred.paCred = &pCertContext;

Status = g_pSSPI->AcquireCredentialsHandleA(
NULL, // Name of principal
UNISP_NAME_A, // Name of package
SECPKG_CRED_OUTBOUND, // Flags indicating use
NULL, // Pointer to logon ID
&SchannelCred, // Package specific data
NULL, // Pointer to GetKey() func
NULL, // Value to pass to GetKey()
&hCreds, // (out) Cred Handle
&tsExpiry); // (out) Lifetime (optional)
if(Status != SEC_E_OK)
{
printf("**** Error 0x%x returned by AcquireCredentialsHandle\n", Status);
continue;
}
printf("\nnew schannel credential created\n");
Post by lelteto
Did you install the USB token's CSP? Did you check that the provider ID
(CERT_KEY_PROV_HANDLE_PROP_ID) when you call
CertGetCertificateContextProperty points to the USB token's CSP?
Laszlo Elteto
SafeNet, Inc.
Post by Lingyan
I am using the SSL sample code (Microsoft
SDK\Samples\security\SSPI\SSL\WebClient) to establish SSL tunnels with a
server. I have been able to use client certificate without any problem until
today I have to try a USB-token. From the trace it looks like I got the
pChainContext = CertFindChainInStore(m_hMyCertStore,
X509_ASN_ENCODING,
0,
CERT_CHAIN_FIND_BY_ISSUER,
&FindByIssuerPara,
pChainContext);
But when I try to call the following function to create the new credential
with the certificate it fails with error code 0x8009030D.
Status = g_pSSPI->AcquireCredentialsHandleA(
NULL, // Name of principal
UNISP_NAME_A, // Name of package
SECPKG_CRED_OUTBOUND, // Flags indicating use
NULL, // Pointer to logon ID
&m_SchannelCred, // Package specific data
NULL, // Pointer to GetKey()
func
NULL, // Value to pass to
GetKey()
&hCreds, // (out) Cred Handle
&tsExpiry); // (out) Lifetime
(optional)
Any thoughts? Thanks!
lelteto
2005-04-04 16:49:04 UTC
Permalink
So how the cert went to your certificate store? you simply COPIED it from the
token? That's not enough as you probably did not copy the PRIVATE KEY with
it. (And the point of using tokens is not to export the private key from it
and use it in the much less secure software environment. In fact, the reason
one uses token that the private key is secure within the token, ie. never
leaves the token.) Obviously, when the certificate is used only with the
PUBLIC KEY (eg. to send an email to somebody) taht's enough as the public key
is embedded in the cert. However, when you want to use the cert for SSL
client authentication than the server wants the client to prove it has the
private key, so you need to use it. If it's on the token than you need the
necessary software (token vendor's CSP) to get access to the private key.
Usually there is a utility which allows you to copy certificates on the token
into your certificate store in the way which points the proper CSP. (Some
tokens do the copying automatically whenever you insert the token and delete
the cert from your store when the token removed.)

Laszlo Elteto
SafeNet, Inc.
Post by Lingyan
No, I didn't install any CSP and I didn't use
CertGetCertificateContextProperty. The following is the sample code I used. I
thought this should behave the same as IE. IE can use the certificate and
access the server without any problem. In the following code
AcquireCredentialsHandleA returned SEC_E_UNKNOWN_CREDENTIALS.
// Find a certificate chain.
pChainContext = CertFindChainInStore(hMyCertStore,
X509_ASN_ENCODING,
0,
CERT_CHAIN_FIND_BY_ISSUER,
&FindByIssuerPara,
pChainContext);
if(pChainContext == NULL)
{
printf("Error 0x%x finding cert chain\n", GetLastError());
break;
}
printf("\ncertificate chain found\n");
// Get pointer to leaf certificate context.
pCertContext = pChainContext->rgpChain[0]->rgpElement[0]->pCertContext;
// Create schannel credential.
SchannelCred.dwVersion = SCHANNEL_CRED_VERSION;
SchannelCred.cCreds = 1;
SchannelCred.paCred = &pCertContext;
Status = g_pSSPI->AcquireCredentialsHandleA(
NULL, // Name of principal
UNISP_NAME_A, // Name of package
SECPKG_CRED_OUTBOUND, // Flags indicating use
NULL, // Pointer to logon ID
&SchannelCred, // Package specific data
NULL, // Pointer to GetKey() func
NULL, // Value to pass to GetKey()
&hCreds, // (out) Cred Handle
&tsExpiry); // (out) Lifetime (optional)
if(Status != SEC_E_OK)
{
printf("**** Error 0x%x returned by AcquireCredentialsHandle\n", Status);
continue;
}
printf("\nnew schannel credential created\n");
Post by lelteto
Did you install the USB token's CSP? Did you check that the provider ID
(CERT_KEY_PROV_HANDLE_PROP_ID) when you call
CertGetCertificateContextProperty points to the USB token's CSP?
Laszlo Elteto
SafeNet, Inc.
Post by Lingyan
I am using the SSL sample code (Microsoft
SDK\Samples\security\SSPI\SSL\WebClient) to establish SSL tunnels with a
server. I have been able to use client certificate without any problem until
today I have to try a USB-token. From the trace it looks like I got the
pChainContext = CertFindChainInStore(m_hMyCertStore,
X509_ASN_ENCODING,
0,
CERT_CHAIN_FIND_BY_ISSUER,
&FindByIssuerPara,
pChainContext);
But when I try to call the following function to create the new credential
with the certificate it fails with error code 0x8009030D.
Status = g_pSSPI->AcquireCredentialsHandleA(
NULL, // Name of principal
UNISP_NAME_A, // Name of package
SECPKG_CRED_OUTBOUND, // Flags indicating use
NULL, // Pointer to logon ID
&m_SchannelCred, // Package specific data
NULL, // Pointer to GetKey() func
NULL, // Value to pass to GetKey()
&hCreds, // (out) Cred Handle
&tsExpiry); // (out) Lifetime (optional)
Any thoughts? Thanks!
Loading...