question

rajliyanthnelaparthi-9385 avatar image
0 Votes"
rajliyanthnelaparthi-9385 asked rajliyanthnelaparthi-9385 edited

verify the clientcertificate on the server-side manually

We are using Schannel to implement tls communication between server and client. We have implemented the attached code, we are able to manually verify the server certificate on the client side, we are getting server certificate on client-side bu using

   Status = QueryContextAttributes(&hContext, SECPKG_ATTR_REMOTE_CERT_CONTEXT, (PVOID)&pRemoteCertContext);

and we are able to very the certificate by passing the pRemoteCertContext to CertGetCertificateChain and followed by CertVerifyCertificateChainPolicy.
We have a requirement to verify the client certificate on the server-side manually. We tried different combinations of flags for schannelcred and fContextReq on the server and client-side. We failed with different errors like 0x80090302 returned by InitializeSecurityContext. If we succeed in the handshake we will fail at :
Status = QueryContextAttributes(&hContext, SECPKG_ATTR_REMOTE_CERT_CONTEXT, (PVOID)&pRemoteCertContext);
with 0x80090301 error code
For the detailed code please go through the links client and server
Client-side code

these falgs were passed to InitializeSecurityContextA for the handshake

   dwSSPIFlags = ISC_REQ_SEQUENCE_DETECT   |
                 ISC_REQ_REPLAY_DETECT     |
                 ISC_REQ_CONFIDENTIALITY   |
                 ISC_RET_EXTENDED_ERROR    |
                 ISC_REQ_ALLOCATE_MEMORY   |
                 ISC_REQ_STREAM | ISC_REQ_MANUAL_CRED_VALIDATION |
                                     ISC_REQ_MUTUAL_AUTH;;

We used the below method to get the certificate and create schannelcred on client side



 cert_store = CertOpenStore(CERT_STORE_PROV_SYSTEM,
                 PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
                 NULL,
                 CERT_SYSTEM_STORE_LOCAL_MACHINE,
                 L"MY");
 if(!cert_store) {
     printf("\nschannel: Failed to open cert store last error is 0x%x", GetLastError());
 }
 client_cert = CertFindCertificateInStore(cert_store, 
                     X509_ASN_ENCODING, 
                     0,
                     CERT_FIND_HASH,
                     &blob,
                     NULL);
 if(client_cert == NULL)
 {
     printf("\n\ncertificate not found");
     return -1;
 }
 else
     printf("\n\ncertificate found");


 // Build Schannel credential structure. Currently, this sample only
 // specifies the protocol to be used (and optionally the certificate,
 // of course). Real applications may wish to specify other parameters as well.
 ZeroMemory( &SchannelCred, sizeof(SchannelCred) );
 SchannelCred.dwVersion  = SCHANNEL_CRED_VERSION;
 if(client_cert)
 {
     SchannelCred.cCreds     = 1;
     SchannelCred.paCred     = &client_cert;
 }

 SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_CLIENT;
 SchannelCred.dwFlags =  SCH_CRED_MANUAL_CRED_VALIDATION | SCH_CRED_NO_DEFAULT_CREDS |  
                     SCH_CRED_IGNORE_NO_REVOCATION_CHECK | SCH_CRED_IGNORE_REVOCATION_OFFLINE ;

above flags were set for the schannel cred structure



 // Create an SSPI credential.
 Status = AcquireCredentialsHandle(NULL,                 // Name of principal    
             UNISP_NAME,         // 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()
             phCreds,              // (out) Cred Handle
             &tsExpiry );          // (out) Lifetime (optional)



Server-side code:

below flags were passed to AcceptSecurityContext for the handshake

 DWORD dwSSPIFlags =
        ASC_REQ_SEQUENCE_DETECT |
        ASC_REQ_REPLAY_DETECT |
        ASC_REQ_CONFIDENTIALITY |
        ASC_REQ_EXTENDED_ERROR |
        ASC_REQ_ALLOCATE_MEMORY |
        ASC_REQ_STREAM |
            ASC_REQ_MUTUAL_AUTH;

We used the below method to get the certificate and create schannelcred on serverside


cert_store = CertOpenStore(CERT_STORE_PROV_SYSTEM,
PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
NULL,
CERT_SYSTEM_STORE_LOCAL_MACHINE,
L"MY");
if(!cert_store) {
printf("\nschannel: Failed to open cert store last error is 0x%x", GetLastError());
}
client_cert = CertFindCertificateInStore(cert_store,
X509_ASN_ENCODING,
0,
CERT_FIND_HASH,
&blob,
NULL);
if(client_cert == NULL)
{
printf("\n\ncertificate not found");
//return -1;
}
else
printf("\n\ncertificate found");


 // Build Schannel credential structure. Currently, this sample only
 // specifies the protocol to be used (and optionally the certificate,
 // of course). Real applications may wish to specify other parameters as well.
 ZeroMemory( &SchannelCred, sizeof(SchannelCred) );
 SchannelCred.dwVersion  = SCHANNEL_CRED_VERSION;
 if(client_cert)
 {
     SchannelCred.cCreds     = 1;
     SchannelCred.paCred     = &client_cert;
 }

 SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_CLIENT;
 SchannelCred.dwFlags =  SCH_CRED_MANUAL_CRED_VALIDATION | SCH_CRED_NO_DEFAULT_CREDS |
                     SCH_CRED_IGNORE_NO_REVOCATION_CHECK | SCH_CRED_IGNORE_REVOCATION_OFFLINE ;


 // Create an SSPI credential.
 Status = AcquireCredentialsHandle(NULL,                 // Name of principal    
             UNISP_NAME,         // 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()
             phCreds,              // (out) Cred Handle
             &tsExpiry );          // (out) Lifetime (optional)

With these flags set we are failing with 0x80090302 returned by InitializeSecurityContext.


For the detailed code please go through the links client and server











windows-api
· 3
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Client:

certificate not found----- Credentials Initialized

Server:

certificate not found

How do I get these certificates?

0 Votes 0 ·

115353-new-text-document.txt
We used the commands in the text file attached to generate the self signed certificates.

0 Votes 0 ·

I'm sorry. Have you seen The SSL sample?


0 Votes 0 ·

0 Answers