Search code examples
windowsnetwork-programmingschannel

Determine attributes of an Schannel connection -> returns unknown value


After successfully Creating a Secure Connection Using Schannel, I am obtaining its connection attributes using QueryContextAttributes(), passing SECPKG_ATTR_CONNECTION_INFO.

The returned structure SecPkgContext_ConnectionInfo contains the field aiExch, which holds the information I am looking for - namely the used key exchange algorithm.

I am using this for months, and it always returned one of the two predefined values CALG_RSA_KEYX or CALG_DH_EPHEM. But since a couple of weeks (when I believe a Schannel update patch was issued by Microsoft) it returns an unknown value: 0x0000ae06

Using these macros, the ALG_ID can be split into its components:

#define GET_ALG_CLASS(x)                (x & (7 << 13))
#define GET_ALG_TYPE(x)                 (x & (15 << 9))
#define GET_ALG_SID(x)                  (x & (511))

According to that, 0x0000ae06 would mean:

Class: ALG_CLASS_KEY_EXCHANGE
Type: (7 << 9) -> which is undefined
SID: 6 -> whose meaning depends on the type of algorithm

Anyone ran into the same issue? Can anyone explain what happened, or what 0x0000ae06 stands for?


Solution

  • Have a look at the code found here http://pastebin.com/TKQJ85Z9 notice that, the ID was added to the schannel library but apparently the VC headers weren't update, at any rate, as you can see from the above code (see pastebin URL), that ID corresponds to "ECDHE", that is Elliptic Curve DH with Ephemeral key exchange

    [edit]

    The real problem is that the value is unofficial and can only be found by some internet search, that's why I posted the link to some sample code; see, it just happened to me to find the answer by looking at this twit https://twitter.com/ericlaw/status/301083494203928576

    At any rate, it sounds like the latest version of the Microsoft CNG SDK contains updated headers and libraries which add a new constant for the "QueryContextAttributes" API call, that is SECPKG_ATTR_CIPHER_INFO such a call returns a structure (see definition in code below) whose member named "szCipherSuite" reports the full string for the cipher in use, for example "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384_P384"

    Here's some sample code for such a call

    /*
    // -- http://www.microsoft.com/en-us/download/details.aspx?id=1251
    typedef struct _SecPkgContext_CipherInfo
    {
    
        DWORD dwVersion;
        DWORD dwProtocol;
        DWORD dwCipherSuite;
        DWORD dwBaseCipherSuite;
        WCHAR szCipherSuite[SZ_ALG_MAX_SIZE];
        WCHAR szCipher[SZ_ALG_MAX_SIZE];
        DWORD dwCipherLen;
        DWORD dwCipherBlockLen;    // in bytes
        WCHAR szHash[SZ_ALG_MAX_SIZE];
        DWORD dwHashLen;
        WCHAR szExchange[SZ_ALG_MAX_SIZE];
        DWORD dwMinExchangeLen;
        DWORD dwMaxExchangeLen;
        WCHAR szCertificate[SZ_ALG_MAX_SIZE];
        DWORD dwKeyType;
    } SecPkgContext_CipherInfo, *PSecPkgContext_CipherInfo;
    */    
    
    static void DisplayConnectionInfo(CtxtHandle *phContext)
    {
      SECURITY_STATUS Status;
      SecPkgContext_CipherInfo CipherInfo = { SECPKGCONTEXT_CIPHERINFO_V1 };
    
      Status = QueryContextAttributes( phContext, SECPKG_ATTR_CIPHER_INFO, &CipherInfo);    
      if(Status != SEC_E_OK) 
      { 
        printf("Error 0x%x querying cipher info\n", Status); 
        return; 
      }
    
      printf("%S\n", CipherInfo.szCipherSuite);
    }
    

    for further infos, please get the MS CNG SDK and have a look at the included help and headers.