How To Programmatically Determine the Cipher Strength on Windows (259122)



The information in this article applies to:

  • Microsoft Win32 Application Programming Interface (API)

This article was previously published under Q259122

SUMMARY

To determine the cipher strength of a system programmatically, you can query schannel by calling QueryCredentialsAttributes.

QueryCredentialsAttributes can be called on all windows platforms.

MORE INFORMATION

The following source code will determine the cipher strength on a system:
#include <windows.h>
#include <stdio.h>
#define SECURITY_WIN32
#include <schannel.h>
#include <sspi.h> 
#include <issperr.h> 

typedef PSecurityFunctionTable (APIENTRY *INITSECURITYINTERFACE_FN_A) (VOID);

void PrintStatus(SECURITY_STATUS Status);
DWORD GetCipherStrength();

void main()
{
   DWORD dwCipherStrength;

   dwCipherStrength = GetCipherStrength();

   if (dwCipherStrength > 0)
   {
      printf("\nCipher Strength : %d bits\n", dwCipherStrength);
   }
   else
   {
      printf("Unable to get Cipher Strength.\n");
   }
}

// Returns the maximum cipher strength
// If cipher strength is 168bit it means 128bit
DWORD GetCipherStrength()
{
    DWORD                           dwKeySize = 0;
    HINSTANCE                       hSecurity = 0;
    INITSECURITYINTERFACE_FN_A      pfnInitSecurityInterfaceA;
    PSecurityFunctionTable          pSecFuncTable;
        
    __try
    {       
       hSecurity = LoadLibrary("schannel");              
       if (!hSecurity)
       {
           printf("Unable to load library.\n");
           __leave;
       }    

       pfnInitSecurityInterfaceA =
           (INITSECURITYINTERFACE_FN_A)GetProcAddress(hSecurity, "InitSecurityInterfaceA");

       if (pfnInitSecurityInterfaceA == NULL)
       {
          printf("Unable to get InitSecurityInterfaceA address\n");
          __leave;
       }

       pSecFuncTable = (PSecurityFunctionTable)((*pfnInitSecurityInterfaceA)());
       if (pSecFuncTable == NULL)
       {
          printf("InitSecurityInterfaceA did not return function table.\n");
          __leave;
       }

       if (pSecFuncTable->AcquireCredentialsHandleA && pSecFuncTable->QueryCredentialsAttributesA)
       {
           TimeStamp  tsExpiry;
           CredHandle chCred;
           SecPkgCred_CipherStrengths cs;
           SECURITY_STATUS Status;
           SCHANNEL_CRED credData;

           ZeroMemory(&credData, sizeof(credData));
           credData.dwVersion = SCHANNEL_CRED_VERSION;

           // Acquire the credentials
           Status = (*pSecFuncTable->AcquireCredentialsHandleA)(NULL,  
                             UNISP_NAME_A, // Package
                             SECPKG_CRED_OUTBOUND,
                             NULL,
                             &credData,
                             NULL,
                             NULL,
                             &chCred,      // Handle
                             &tsExpiry );
           if (Status == SEC_E_OK)
           { 
               // Query the Cipher Strength              
               Status = (*pSecFuncTable->QueryCredentialsAttributesA)(&chCred,
                                              SECPKG_ATTR_CIPHER_STRENGTHS, 
                                              &cs);
               if (Status == SEC_E_OK)
               {
                   dwKeySize = cs.dwMaximumCipherStrength;                   
               }
               else
               {  
                  printf("QueryCredentialsAttributesA failed with %x: ", Status);
                  PrintStatus(Status);
               }

               // Free the handle if we can
               if (pSecFuncTable->FreeCredentialsHandle)
               {
                   (*pSecFuncTable->FreeCredentialsHandle)(&chCred);
               }
           }
           else
           {
               printf("AcquireCredentialsHandleA failed with %x: ", Status);
               PrintStatus(Status);
           }
       }
       else
       {
          printf("AcquireCredentialsHandleA or QueryCredentialsAttributeA are NULL.\n");
       }
    }
    __finally
    {
       if (hSecurity) FreeLibrary(hSecurity);
    }

    return (dwKeySize >= 168 ? 128 : dwKeySize);
}

void PrintStatus(SECURITY_STATUS Status)
{
    switch (Status)
    {
        case SEC_E_UNSUPPORTED_FUNCTION:
           printf("Unsupported Function.\n");
           break;
        case SEC_E_INVALID_HANDLE:
           printf("Unsupported Function.\n");
           break;
    }
}
				

Modification Type:MinorLast Reviewed:7/2/2004
Keywords:kbhowto KB259122