/* Copyright (c) 1997, Microsoft Corporation, all rights reserved File: eaptls.h Description: PPP EAP TLS Authentication Protocol. Based on RFC xxxx. History: Oct 9, 1997: Vijay Baliga created original version. */ #ifndef _EAPTLS_H_ #define _EAPTLS_H_ #define EAPTLS_KEY_13 L"System\\CurrentControlSet\\Services\\Rasman\\PPP\\EAP\\13" #define EAPTLS_VAL_SERVER_CONFIG_DATA L"ServerConfigData" #define EAPTLS_VAL_MAX_TLS_MESSAGE_LENGTH L"MaxTLSMessageLength" #define EAPTLS_VAL_IGNORE_NO_REVOCATION_CHECK L"IgnoreNoRevocationCheck" #define EAPTLS_VAL_IGNORE_REVOCATION_OFFLINE L"IgnoreRevocationOffline" #define EAPTLS_VAL_NO_ROOT_REVOCATION_CHECK L"NoRootRevocationCheck" #define EAPTLS_VAL_NO_REVOCATION_CHECK L"NoRevocationCheck" #define EAPTLS_8021x_PIN_DATA_DESCR L"starcehvionrsf" #define MAX_HASH_SIZE 20 // Certificate hash size // EAPTLS_PACKET flags #define EAPTLS_PACKET_FLAG_LENGTH_INCL 0x80 #define EAPTLS_PACKET_FLAG_MORE_FRAGMENTS 0x40 #define EAPTLS_PACKET_FLAG_TLS_START 0x20 // // Versioning for PEAP. This will include the highest and lowest // supported versions // #define EAPTLS_PACKET_HIGHEST_SUPPORTED_VERSION 0x00 #define EAPTLS_PACKET_LOWEST_SUPPORTED_VERSION 0x00 #define EAPTLS_PACKET_CURRENT_VERSION 0x00 typedef struct _EAPTLS_PACKET { BYTE bCode; // See EAPCODE_* BYTE bId; // Id of this packet BYTE pbLength[2]; // Length of this packet BYTE bType; // Should be PPP_EAP_TLS // (only for Request, Response) BYTE bFlags; // See EAPTLS_PACKET_FLAG_* // (only for Request, Response) BYTE pbData[1]; // Data // (only for Request, Response) } EAPTLS_PACKET; #define EAPTLS_PACKET_HDR_LEN (sizeof(EAPTLS_PACKET) - 1) // The largest EAP TLS header has 4 more octects for TLS blob size #define EAPTLS_PACKET_HDR_LEN_MAX (EAPTLS_PACKET_HDR_LEN + 4) // EAP TLS states typedef enum EAPTLS_STATE { EAPTLS_STATE_INITIAL, EAPTLS_STATE_SENT_START, // Server only EAPTLS_STATE_SENT_HELLO, EAPTLS_STATE_SENT_FINISHED, EAPTLS_STATE_RECD_FINISHED, // Client only EAPTLS_STATE_SENT_RESULT, // Server only EAPTLS_STATE_RECD_RESULT, // Client only EAPTLS_STATE_WAIT_FOR_USER_OK // Client only } EAPTLS_STATE; // Highest number we can handle #define EAPTLS_STATE_LIMIT EAPTLS_STATE_RECD_RESULT typedef struct _EAPTLS_HASH { DWORD cbHash; // Number of bytes in the hash BYTE pbHash[MAX_HASH_SIZE]; // The hash of a certificate } EAPTLS_HASH; // Values of the EAPTLS_CONN_PROPERTIES->fFlags field // Use a certificate on this machine #define EAPTLS_CONN_FLAG_REGISTRY 0x00000001 // Do not validate server cert #define EAPTLS_CONN_FLAG_NO_VALIDATE_CERT 0x00000002 // Do not Validate server name #define EAPTLS_CONN_FLAG_NO_VALIDATE_NAME 0x00000004 // Send a different EAP Identity #define EAPTLS_CONN_FLAG_DIFF_USER 0x00000008 // User simple cert selection logic #define EAPTLS_CONN_FLAG_SIMPLE_CERT_SEL 0x00000010 #define EAPTLS_CONN_PROP_WATERMARK 0xBEEFFEEB // // EAPTLS_CONN_PROPERTIES + EAPTLS_CONN_PROPERTIES_V1_EXTRA // are send back to the calling application. However, internally // EAPTLS_CONN_PROPERTIES_V1 is used. // typedef struct _EAPTLS_CONN_PROPERTIES { DWORD dwVersion; //Version will be 1 for this release DWORD dwSize; // Number of bytes in this structure DWORD fFlags; // See EAPTLS_CONN_FLAG_* EAPTLS_HASH Hash; // Hash of the first certificate WCHAR awszServerName[1]; // server name of the first server } EAPTLS_CONN_PROPERTIES; // // This is a very messy way of doing things // but cannot help it because the verion // checking on the data structure was not // done to begin with. Hopefully some day // we will be able to get away from this // deal. Other part of the story is CM is // unable to create targetted connectoids. // So we have to carry this structure going // ahead unless CM is smart about targetted // connectoids. // // Additional stuff required in // version 1 of data structure // typedef struct _EAPTLS_CONN_PROPERTIES_V1_EXTRA { DWORD dwNumHashes; // Number of Hashes in the // structure including the one // in v0 struct above BYTE bData[1]; // Data - contains an array of // EAPTLS_HASH structures followed by // a string specifying server names // minus the first server }EAPTLS_CONN_PROPERTIES_V1_EXTRA; //The new v1.0 structure used internally typedef struct _EAPTLS_CONN_PROPERTIES_V1 { DWORD dwVersion; // Version will be 1 for this release DWORD dwSize; // Number of bytes in this structure DWORD fFlags; // See EAPTLS_CONN_FLAG_* DWORD dwNumHashes; // Number of hash structures in the list BYTE bData[1]; // Data - contains an array of // EAPTLS_HASH structures followed by // a string specifying server name }EAPTLS_CONN_PROPERTIES_V1; // The old 'PIN must be saved' flag #define EAPTLS_USER_FLAG_OLD_SAVE_PIN 0x00000001 // The PIN must be saved #define EAPTLS_USER_FLAG_SAVE_PIN 0x00000002 typedef struct _EAPTLS_USER_PROPERTIES { DWORD reserved; // Must be 0 (compare with EAPLOGONINFO) DWORD dwVersion; DWORD dwSize; // Number of bytes in this structure DWORD fFlags; // See EAPTLS_USER_FLAG_* EAPTLS_HASH Hash; // Hash for the user certificate WCHAR* pwszDiffUser; // The EAP Identity to send DWORD dwPinOffset; // Offset in abData WCHAR* pwszPin; // The smartcard PIN USHORT usLength; // Part of UnicodeString USHORT usMaximumLength; // Part of UnicodeString UCHAR ucSeed; // To unlock the UnicodeString WCHAR awszString[1]; // Storage for pwszDiffUser and pwszPin } EAPTLS_USER_PROPERTIES; typedef struct _EAPTLS_PIN { WCHAR *pwszPin; USHORT usLength; USHORT usMaximumLength; UCHAR ucSeed; } EAPTLS_PIN; // Values of the EAPTLSCB->fFlags field // We are the server #define EAPTLSCB_FLAG_SERVER 0x00000001 // We are a router #define EAPTLSCB_FLAG_ROUTER 0x00000002 // The call is happening during logon #define EAPTLSCB_FLAG_LOGON 0x00000004 // Negotiation is complete, and so far appears successful. A server may get a // TLS Alert message from the client at this point, in which case it will // realize that the negotiation was unsuccessful. However, a client never // changes its mind. #define EAPTLSCB_FLAG_SUCCESS 0x00000008 // The peer has a large blob to send. So it has divided it into fragments #define EAPTLSCB_FLAG_RECEIVING_FRAGMENTS 0x00000010 // Keeps track of whether we need to call FreeCredentialsHandle(hCredential) #define EAPTLSCB_FLAG_HCRED_INVALID 0x00000020 // Keeps track of whether we need to call DeleteSecurityContext(hContext) #define EAPTLSCB_FLAG_HCTXT_INVALID 0x00000040 // We are not allowed to display any UI #define EAPTLSCB_FLAG_NON_INTERACTIVE 0x00000080 // This is the first link in a multilink bundle. This is not a callback. #define EAPTLSCB_FLAG_FIRST_LINK 0x00000100 // The user data was obtained from Winlogon #define EAPTLSCB_FLAG_WINLOGON_DATA 0x00000200 // We are doing Machine Authentication #define EAPTLSCB_FLAG_MACHINE_AUTH 0x00000400 // We are providing guest access #define EAPTLSCB_FLAG_GUEST_ACCESS 0x00000800 //We want to do something specific to 8021x auth #define EAPTLSCB_FLAG_8021X_AUTH 0x00001000 //We are using cached credentials #define EAPTLSCB_FLAG_USING_CACHED_CREDS 0x00002000 //We are running in PEAP context #define EAPTLSCB_FLAG_EXECUTING_PEAP 0x00004000 // The EAP TLS work buffer typedef struct _EAPTLS_CONTROL_BLOCK { EAPTLS_STATE EapTlsState; DWORD fFlags; // See EAPTLSCB_FLAG_* HANDLE hTokenImpersonateUser; // Client only WCHAR awszIdentity[UNLEN + 1];// Server only RAS_AUTH_ATTRIBUTE* pAttributes; // Username or MPPE key EAPTLS_CONN_PROPERTIES_V1* pConnProp; // Client only EAPTLS_CONN_PROPERTIES_V1 * pNewConnProp;// Client only EAPTLS_USER_PROPERTIES* pUserProp; // Client only, EAPTLSCB_FLAG_LOGON only BYTE* pUserData; DWORD dwSizeOfUserData; PCCERT_CONTEXT pCertContext; CredHandle hCredential; // The credentials handle CtxtHandle hContext; // The context handle ULONG fContextReq; // Required context attributes BYTE* pbBlobIn; // TLS blob received from the peer DWORD cbBlobIn; // Number of bytes in the TLS blob // received from the peer DWORD cbBlobInBuffer; // Number of bytes allocated for the // pbBlobIn buffer DWORD dwBlobInRemining; // We are receiving fragments from // the peer and the peer has // promised to send dwBlobInRemining // more bytes BYTE* pbBlobOut; // TLS blob created for the peer DWORD cbBlobOut; // Number of bytes in the TLS blob // created for the peer DWORD cbBlobOutBuffer; // Number of bytes allocated for the // pbBlobOut buffer DWORD dwBlobOutOffset; // Pointer to the first byte in // pbBlobOut that has to be sent DWORD dwBlobOutOffsetNew; // Update dwBlobOutOffset to this // value when the peer confirms // receipt of the previous packet BYTE bCode; // bCode of the last packet sent BYTE bId; // bId of the last packet sent DWORD dwAuthResultCode; // The error code that we get when // the negotiation is complete EAPTLS_PIN *pSavedPin; // HANDLE hEventLog; BYTE* pUIContextData; BYTE bNextId; // Saved when we raise UI EAPTLS_PACKET ReceivePacket; // Saved when we go off to get PIN } EAPTLSCB; typedef struct _EAPTLS_CERT_NODE EAPTLS_CERT_NODE; struct _EAPTLS_CERT_NODE { EAPTLS_CERT_NODE* pNext; EAPTLS_HASH Hash; WCHAR* pwszDisplayName; WCHAR* pwszFriendlyName; WCHAR* pwszIssuer; WCHAR* pwszExpiration; // // New fields added vivekk // FILETIME IssueDate; #if 0 WCHAR* pwszIssuedTo; WCHAR* pwszIssuedBy; #endif }; // Values of the EAPTLS_CONN_DIALOG->fFlags field // We are a router #define EAPTLS_CONN_DIALOG_FLAG_ROUTER 0x00000001 #define EAPTLS_CONN_DIALOG_FLAG_READONLY 0x00000002 typedef struct _EAPTLS_CONN_DIALOG { DWORD fFlags; // See // EAPTLS_CONN_DIALOG_FLAG_* EAPTLS_CERT_NODE* pCertList; //List of all the root certificates //from internet trusted root store EAPTLS_CERT_NODE** ppSelCertList; //List of pointers to selected certs. //will be as many as num hashes //in conn prop. EAPTLS_CONN_PROPERTIES* pConnProp; // ConfigData in phonebook EAPTLS_CONN_PROPERTIES_V1 * pConnPropv1; // Version 1.0 config data HWND hWndRadioUseCard; HWND hWndRadioUseRegistry; HWND hWndCheckValidateCert; HWND hWndCheckValidateName; HWND hWndEditServerName; HWND hWndStaticRootCaName; //HWND hWndComboRootCaName; //This will go away HWND hWndListRootCaName; //This is the new list HWND hWndCheckDiffUser; HWND hWndCheckUseSimpleSel; HWND hWndViewCertDetails; } EAPTLS_CONN_DIALOG; // Values of the EAPTLS_USER_DIALOG->fFlags field // We need to send a different EAP Identity #define EAPTLS_USER_DIALOG_FLAG_DIFF_USER 0x00000001 // We need to change the title #define EAPTLS_USER_DIALOG_FLAG_DIFF_TITLE 0x00000002 //USe simple cert selection #define EAPTLS_USER_DIALOG_FLAG_USE_SIMPLE_CERTSEL 0x00000004 // // Nodes are grouped by displayname // typedef struct _EAPTLS_GROUPED_CERT_NODES EAPTLS_GROUPED_CERT_NODES; typedef struct _EAPTLS_GROUPED_CERT_NODES* PEAPTLS_GROUPED_CERT_NODES; struct _EAPTLS_GROUPED_CERT_NODES { PEAPTLS_GROUPED_CERT_NODES pNext; WCHAR* pwszDisplayName; //Most current one in the colation... EAPTLS_CERT_NODE* pMostRecentCert; }; typedef struct _EAPTLS_USER_DIALOG { DWORD fFlags; // See // EAPTLS_USER_DIALOG_FLAG_* EAPTLS_CERT_NODE* pCertList; EAPTLS_CERT_NODE* pCert; PEAPTLS_GROUPED_CERT_NODES pGroupedList; EAPTLS_USER_PROPERTIES* pUserProp; // UserData in registry const WCHAR* pwszEntry; const WCHAR* pwszStoreName; BOOL fIdentity; //Identity UI is being shown here HWND hWndComboUserName; HWND hWndBtnViewCert; // These are required for the server's certificate selection HWND hWndEditFriendlyName; HWND hWndEditIssuer; HWND hWndEditExpiration; HWND hWndStaticDiffUser; HWND hWndEditDiffUser; } EAPTLS_USER_DIALOG; // Values of the EAPTLS_PIN_DIALOG->fFlags field // We need to send a different EAP Identity #define EAPTLS_PIN_DIALOG_FLAG_DIFF_USER 0x00000001 // The UI is coming up before Logon #define EAPTLS_PIN_DIALOG_FLAG_LOGON 0x00000002 #define EAPTLS_PIN_DIALOG_FLAG_ROUTER 0x00000004 typedef struct _EAPTLS_PIN_DIALOG { DWORD fFlags; // See // EAPTLS_PIN_DIALOG_FLAG_* EAPTLS_USER_PROPERTIES* pUserProp; // UserData in registry const WCHAR* pwszEntry; PCCERT_CONTEXT pCertContext; //Certificate Context for selected certificate. DWORD dwRetCode; //Return Code of Validate PIN operation. HWND hWndStaticDiffUser; HWND hWndEditDiffUser; HWND hWndStaticPin; HWND hWndEditPin; } EAPTLS_PIN_DIALOG; #define NUM_CHARS_TITLE 100 typedef struct _EAPTLS_VALIDATE_SERVER { DWORD dwSize; DWORD fShowCertDetails; EAPTLS_HASH Hash; //Hash of the root certificate to show details WCHAR awszTitle[NUM_CHARS_TITLE]; WCHAR awszWarning[1]; } EAPTLS_VALIDATE_SERVER; #ifdef ALLOC_EAPTLS_GLOBALS DWORD g_dwEapTlsTraceId = INVALID_TRACEID; int g_nEapTlsClientNextState[] = { EAPTLS_STATE_SENT_HELLO, EAPTLS_STATE_INITIAL, // Impossible EAPTLS_STATE_SENT_FINISHED, EAPTLS_STATE_RECD_FINISHED, EAPTLS_STATE_RECD_RESULT, EAPTLS_STATE_INITIAL, // Impossible EAPTLS_STATE_RECD_RESULT, EAPTLS_STATE_RECD_FINISHED }; int g_nEapTlsServerNextState[] = { EAPTLS_STATE_SENT_START, EAPTLS_STATE_SENT_HELLO, EAPTLS_STATE_SENT_FINISHED, EAPTLS_STATE_SENT_RESULT, EAPTLS_STATE_INITIAL, // Impossible EAPTLS_STATE_SENT_RESULT, EAPTLS_STATE_INITIAL, // Impossible EAPTLS_STATE_INITIAL, // Impossible }; CHAR *g_szEapTlsState[] = { "Initial", "SentStart", "SentHello", "SentFinished", "RecdFinished", "SentResult", "RecdResult", "WaitForUserOK", }; #else // !ALLOC_EAPTLS_GLOBALS extern DWORD g_dwEapTlsTraceId; #endif // ALLOC_EAPTLS_GLOBALS // Prototypes for functions in util.c VOID EapTlsTrace( IN CHAR* Format, ... ); DWORD EapTlsInitialize2( IN BOOL fInitialize, IN BOOL fUI ); DWORD EapTlsInitialize( IN BOOL fInitialize ); VOID EncodePin( IN EAPTLS_USER_PROPERTIES* pUserProp ); VOID DecodePin( IN EAPTLS_USER_PROPERTIES* pUserProp ); BOOL FFormatMachineIdentity1 ( LPWSTR lpszMachineNameRaw, LPWSTR * lppszMachineNameFormatted ); BOOL FFormatMachineIdentity ( IN LPWSTR lpszMachineNameRaw, OUT LPWSTR * lppszMachineNameFormatted ); BOOL FCertToStr( IN PCCERT_CONTEXT pCertContext, IN DWORD fFlags, IN BOOL fMachineCert, OUT WCHAR** ppwszName ); BOOL FMachineAuthCertToStr ( IN PCCERT_CONTEXT pCertContext, OUT WCHAR ** ppwszName ); BOOL FGetFriendlyName( IN PCCERT_CONTEXT pCertContext, OUT WCHAR** ppwszName ); BOOL FSmartCardReaderInstalled( VOID ); DWORD DwGetEKUUsage ( IN PCCERT_CONTEXT pCertContext, OUT PCERT_ENHKEY_USAGE * ppUsage ); BOOL FCheckUsage( IN PCCERT_CONTEXT pCertContext, IN PCERT_ENHKEY_USAGE pUsage, IN BOOL fMachine ); BOOL FCheckSCardCertAndCanOpenSilentContext ( IN PCCERT_CONTEXT pCertContext ); BOOL FCheckCSP( IN PCCERT_CONTEXT pCertContext ); BOOL FCheckTimeValidity( IN PCCERT_CONTEXT pCertContext ); DWORD DwCheckCertPolicy ( IN PCCERT_CONTEXT pCertContextUser, OUT PCCERT_CHAIN_CONTEXT * ppCertChainContext ); DWORD GetRootCertHashAndNameVerifyChain( IN PCERT_CONTEXT pCertContextServer, OUT EAPTLS_HASH* pHash, OUT WCHAR** ppwszName, IN BOOL fVerifyGP, OUT BOOL * pfRootCheckRequired ); DWORD ServerConfigDataIO( IN BOOL fRead, IN WCHAR* pwszMachineName, IN OUT BYTE** ppData, IN DWORD dwNumBytes ); VOID FreeCertList( IN EAPTLS_CERT_NODE* pNode ); VOID CreateCertList( IN BOOL fServer, IN BOOL fRouter, IN BOOL fRoot, OUT EAPTLS_CERT_NODE** ppCertList, OUT EAPTLS_CERT_NODE** ppCert, IN DWORD dwNumHashStructs, IN EAPTLS_HASH* pHash, IN WCHAR* pwszStoreName ); DWORD GetDefaultClientMachineCert( IN HCERTSTORE hCertStore, OUT PCCERT_CONTEXT* ppCertContext ); DWORD GetDefaultMachineCert( IN HCERTSTORE hCertStore, OUT PCCERT_CONTEXT* ppCertContext ); DWORD GetCertFromLogonInfo( IN BYTE* pUserDataIn, IN DWORD dwSizeOfUserDataIn, OUT PCCERT_CONTEXT* ppCertContext ); DWORD GetIdentityFromLogonInfo( IN BYTE* pUserDataIn, IN DWORD dwSizeOfUserDataIn, OUT WCHAR** ppwszIdentity ); DWORD ReadConnectionData( IN BOOL fWireless, IN BYTE* pConnectionDataIn, IN DWORD dwSizeOfConnectionDataIn, OUT EAPTLS_CONN_PROPERTIES** ppConnProp ); DWORD ReadUserData( IN BYTE* pUserDataIn, IN DWORD dwSizeOfUserDataIn, OUT EAPTLS_USER_PROPERTIES** ppUserProp ); DWORD AllocUserDataWithNewIdentity( IN EAPTLS_USER_PROPERTIES* pUserProp, IN WCHAR* pwszIdentity, OUT EAPTLS_USER_PROPERTIES** ppUserProp ); DWORD AllocUserDataWithNewPin( IN EAPTLS_USER_PROPERTIES* pUserProp, IN PBYTE pbzPin, IN DWORD cbPin, OUT EAPTLS_USER_PROPERTIES** ppUserProp ); WCHAR* WszFromId( IN HINSTANCE hInstance, IN DWORD dwStringId ); // Prototypes for functions in eaptls.c DWORD EapTlsBegin( OUT VOID** ppWorkBuffer, IN PPP_EAP_INPUT* pPppEapInput ); DWORD EapTlsEnd( IN EAPTLSCB* pEapTlsCb ); DWORD EapTlsMakeMessage( IN EAPTLSCB* pEapTlsCb, IN PPP_EAP_PACKET* pInput, OUT PPP_EAP_PACKET* pOutput, IN DWORD cbSendPacket, OUT PPP_EAP_OUTPUT* pEapOutput, IN PPP_EAP_INPUT* pEapInput ); DWORD GetCredentials( IN EAPTLSCB* pEapTlsCb ); DWORD EapTlsCMakeMessage( IN EAPTLSCB* pEapTlsCb, IN EAPTLS_PACKET* pReceivePacket, OUT EAPTLS_PACKET* pSendPacket, IN DWORD cbSendPacket, OUT PPP_EAP_OUTPUT* pEapOutput, IN PPP_EAP_INPUT* pEapInput ); DWORD EapTlsSMakeMessage( IN EAPTLSCB* pEapTlsCb, IN EAPTLS_PACKET* pReceivePacket, OUT EAPTLS_PACKET* pSendPacket, IN DWORD cbSendPacket, OUT PPP_EAP_OUTPUT* pEapOutput, IN PPP_EAP_INPUT* pEapInput ); // Prototypes for functions in scard.c DWORD GetCertFromCard( OUT PCCERT_CONTEXT* ppCertContext ); VOID FreeScardDlgDll( VOID ); // Prototypes for functions in eapui.cpp HINSTANCE GetHInstance( VOID ); // Prototypes for functions in dialog.c VOID GetString( IN HWND hwndParent, IN UINT ID, IN OUT WCHAR** ppwszString ); // //Prototypes in eaptls.c // DWORD AssociatePinWithCertificate( IN PCCERT_CONTEXT pCertContext, IN EAPTLS_USER_PROPERTIES* pUserProp, IN BOOL fErarePIN, IN BOOL fCheckNullPin ); DWORD EncryptData ( IN PBYTE pbPlainData, IN DWORD cbPlainData, OUT PBYTE * ppEncData, OUT DWORD * pcbEncData ); // // Prototypes of functions in util.c // DWORD GetMBytePIN ( WCHAR * pwszPIN, CHAR ** ppszPIN ); DWORD VerifyCallerTrust ( void * callersaddress ); #if 0 // //This function get's the hash blob //deposited by Group Policy in the registry // DWORD ReadGPCARootHashes( DWORD *pdwSizeOfRootHashBlob, PBYTE *ppbRootHashBlob ); #endif // // These functions are around the cludgy // CONN PROP structure. // EAPTLS_CONN_PROPERTIES_V1_EXTRA UNALIGNED * ConnPropGetExtraPointer (EAPTLS_CONN_PROPERTIES * pConnProp); DWORD ConnPropGetNumHashes(EAPTLS_CONN_PROPERTIES * pConnProp ); void ConnPropSetNumHashes(EAPTLS_CONN_PROPERTIES * pConnProp, DWORD dwNumHashes ); DWORD ConnPropGetV1Struct ( EAPTLS_CONN_PROPERTIES * pConnProp, EAPTLS_CONN_PROPERTIES_V1 ** ppConnPropv1 ); DWORD ConnPropGetV0Struct ( EAPTLS_CONN_PROPERTIES_V1 * pConnPropv1, EAPTLS_CONN_PROPERTIES ** ppConnProp ); void ShowCertDetails ( HWND hWnd, HCERTSTORE hStore, PCCERT_CONTEXT pCertContext); //////////////////////////All Peap Related Declarations ///////////////////// // // PEAP Message Types // // //TBD: Check with IANA ( ashwinp ) what the type will be. #define PEAP_TYPE_AVP 0x21 // // TLV Format is: // Flags - 2bits // Type - 14 bits // Length - 2 octets // Value - Variable // // TLV Flags // #define PEAP_AVP_FLAG_MANDATORY 0x80 // // TLV types are of following types // // Status TLV. Tell's if the outcome of the EAP is success // or failure. // #define MS_PEAP_AVP_LANGUAGE_NEGOTIATE 0x01 #define MS_PEAP_AVP_CIPHERSUITE_NEGOTIATE 0x02 #define MS_PEAP_AVP_TYPE_STATUS 0x03 // // Values possible in Status AVP // #define MS_PEAP_AVP_VALUE_SUCCESS 0x1 #define MS_PEAP_AVP_VALUE_FAILURE 0x2 // PEAP Reg Keys #define PEAP_KEY_25 L"System\\CurrentControlSet\\Services\\Rasman\\PPP\\EAP\\25" #define PEAP_VAL_SERVER_CONFIG_DATA L"ServerConfigData" // // This key is required for include only MSCHAPv2. IF this is missing all protocols will be included in PEAP // except PEAP itself // #define PEAP_KEY_PEAP L"System\\CurrentControlSet\\Services\\Rasman\\PPP\\EAP\\25" #define PEAP_CRIPPLE_VALUE L"EAPMschapv2Only" #define PEAP_KEY_EAP L"System\\CurrentControlSet\\Services\\Rasman\\PPP\\EAP" #define PEAP_REGVAL_PATH L"Path" #define PEAP_REGVAL_FRIENDLYNAME L"FriendlyName" #define PEAP_REGVAL_CONFIGDLL L"ConfigUIPath" #define PEAP_REGVAL_IDENTITYDLL L"IdentityPath" #define PEAP_REGVAL_INTERACTIVEUIDLL L"InteractiveUIPath" #define PEAP_REGVAL_CONFIGCLSID L"ConfigCLSID" #define PEAP_REGVAL_ROLESSUPPORTED L"RolesSupported" #define PEAP_EAPTYPE_IDENTITY 1 #define PEAP_EAPTYPE_NAK 3 typedef DWORD (APIENTRY * RASEAPFREE)( PBYTE ); typedef DWORD (APIENTRY * RASEAPINVOKECONFIGUI)( DWORD, HWND, DWORD, PBYTE, DWORD, PBYTE*, DWORD*); typedef DWORD (APIENTRY * RASEAPGETIDENTITY)( DWORD, HWND, DWORD, const WCHAR*, const WCHAR*, PBYTE, DWORD, PBYTE, DWORD, PBYTE*, DWORD*, WCHAR** ); typedef DWORD (APIENTRY * RASEAPINVOKEINTERACTIVEUI)( DWORD, HWND, PBYTE, DWORD, PBYTE *, DWORD *); //List of all EAP types allowed in PEAP typedef struct _PEAP_EAP_INFO PEAP_EAP_INFO; typedef struct _PEAP_EAP_INFO* PPEAP_EAP_INFO; struct _PEAP_EAP_INFO { //Next one in the list PPEAP_EAP_INFO pNext; //Type DWORD dwTypeId; // Path of the protocol DLL LPWSTR lpwszPath; //Friendly Name LPWSTR lpwszFriendlyName; //Configuration UI path for client LPWSTR lpwszConfigUIPath; //Identity UI path LPWSTR lpwszIdentityUIPath; //Interactive UI path LPWSTR lpwszInteractiveUIPath; //Configuration GUID LPWSTR lpwszConfigClsId; //Library HAndle HMODULE hEAPModule; //Eap Info for each EAP Type PPP_EAP_INFO PppEapInfo; //Work buffer for each eap type PBYTE pWorkBuf; // Original Client Config from PEAP blob PBYTE pbClientConfigOrig; // Client Config Length DWORD dwClientConfigOrigSize; // New client config PBYTE pbNewClientConfig; // New client config length DWORD dwNewClientConfigSize; // Original User Config information PBYTE pbUserConfigOrig; // Original size of user configuration DWORD dwUserConfigOrigSize; // New user config PBYTE pbUserConfigNew; // New user config size DWORD dwNewUserConfigSize; // DWORD (APIENTRY *RasEapGetCredentials)( IN DWORD dwTypeId, IN VOID * pWorkBuf, OUT VOID ** pInfo); //There will be more items in this node... }; typedef enum _PEAP_STATE { PEAP_STATE_INITIAL, PEAP_STATE_TLS_INPROGRESS, // PEAP-Part 1 (TLS) is being executed PEAP_WAITING_FOR_IDENTITY, // Client should expect and identity request // server should send identity request PEAP_STATE_IDENTITY_REQUEST_SENT, // identity request send by server PEAP_STATE_IDENTITY_RESPONSE_SENT, // identity response send to server PEAP_STATE_EAP_TYPE_INPROGRESS, // PEAP-Part 2 (Embedded EAP) is being // executed PEAP_STATE_EAP_TYPE_FINISHED, // sever should send identity request PEAP_STATE_PEAP_SUCCESS_SEND, // server send PEAP success request PEAP_STATE_PEAP_FAIL_SEND, // server send PEAP fail request PEAP_STATE_FAST_ROAMING_IDENTITY_REQUEST// client is not setup to do fast roaming // and the server send a roaming success // we replied with fail and are now expecting // an identity request from server. } PEAP_STATE; // // connection properties for // each of the peap entries // typedef struct _PEAP_ENTRY_CONN_PROPERTIES { DWORD dwVersion; //Version will be 1 for this release DWORD dwSize; //Number of bytes in this structure DWORD dwEapTypeId; //TypeId for this Entry Properties BYTE bData[1]; //Actual conn properties for the given //Type Id }PEAP_ENTRY_CONN_PROPERTIES, *PPEAP_ENTRY_CONN_PROPERTIES; // // This structure holds EapTlsConn Prop along with // each configured eap type. // // Allow fast roaming #define PEAP_CONN_FLAG_FAST_ROAMING 0x00000001 typedef struct _PEAP_CONN_PROPERTIES { //Version will be 1 for this release DWORD dwVersion; // //Number of bytes in this structure // DWORD dwSize; //Number of types configured in this PEAP //For now there is only one. DWORD dwNumPeapTypes; //Flags DWORD dwFlags; //Tls Connection Properties to start with - This is a variable length structure EAPTLS_CONN_PROPERTIES_V1 EapTlsConnProp; //Array of PPEAP_ENTRY_CONN_PROPERTIES follows here }PEAP_CONN_PROP, *PPEAP_CONN_PROP; // // Default credentials for eaptypes that dont expose // identity UI // typedef struct _PEAP_DEFAULT_CREDENTIALS { WCHAR wszUserName[UNLEN+1]; WCHAR wszPassword[PWLEN+1]; WCHAR wszDomain[DNLEN+1]; }PEAP_DEFAULT_CREDENTIALS, *PPEAP_DEFAULT_CREDENTIALS; // // user properties for // each of the peap entries // typedef struct _PEAP_ENTRY_USER_PROPERTIES { DWORD dwVersion; //Version will be 1 for this release DWORD dwSize; //Number of bytes in this structure DWORD dwEapTypeId; //TypeId for this Entry Properties BOOL fUsingPeapDefault; //Default Identity provided by PEAP is being used. BYTE bData[1]; //Actual User properties for the given //Type Id }PEAP_ENTRY_USER_PROPERTIES, *PPEAP_ENTRY_USER_PROPERTIES; // Allow fast roaming #define PEAP_USER_FLAG_FAST_ROAMING 0x00000001 typedef struct _PEAP_USER_PROPERTIES { //Version will be 1 for this release DWORD dwVersion; //Number of bytes in this structure DWORD dwSize; //Flags DWORD dwFlags; //Hash for user certificate EAPTLS_HASH CertHash; // User properties for an entry PEAP_ENTRY_USER_PROPERTIES UserProperties; // // Array of PEAP_ENTRY_USER_PROPERTIES for each eap type. // should be as many as dwNumPeapTypes in PEAP_CONN_PROP // structure // For now there is only one element... }PEAP_USER_PROP, *PPEAP_USER_PROP; // We are a router #define PEAP_CONN_DIALOG_FLAG_ROUTER 0x00000001 #define PEAP_CONN_DIALOG_FLAG_8021x 0x00000002 typedef struct _PEAP_CONN_DIALOG { DWORD fFlags; // See // PEAP_CONN_DIALOG_FLAG_* EAPTLS_CERT_NODE* pCertList; //List of all the root certificates //from internet trusted root store EAPTLS_CERT_NODE** ppSelCertList; //List of pointers to selected certs. //will be as many as num hashes //in conn prop. PPEAP_CONN_PROP pConnProp; PPEAP_EAP_INFO pEapInfo; //List of all the PEAP Eap Types PPEAP_EAP_INFO pSelEapInfo; //Selected Peap Type HWND hWndCheckValidateCert; HWND hWndCheckValidateName; HWND hWndEditServerName; HWND hWndStaticRootCaName; HWND hWndListRootCaName; HWND hWndComboPeapType; HWND hWndButtonConfigure; HWND hWndCheckEnableFastReconnect; } PEAP_CONN_DIALOG, *PPEAP_CONN_DIALOG; typedef struct _PEAP_SERVER_CONFIG_DIALOG { EAPTLS_CERT_NODE* pCertList; //List of all certificates in MY machine //store EAPTLS_CERT_NODE* pSelCertList; //List of selected cert. PPEAP_USER_PROP pUserProp; //User properties PPEAP_USER_PROP pNewUserProp; //New USer Properties PPEAP_EAP_INFO pEapInfo; //List of all the PEAP Eap Types PPEAP_EAP_INFO pSelEapInfo; //Selected Peap Type LPWSTR pwszMachineName; HWND hWndComboServerName; HWND hWndEditFriendlyName; HWND hWndEditIssuer; HWND hWndEditExpiration; HWND hWndComboPeapType; HWND hWndBtnConfigure; HWND hEndEnableFastReconnect; }PEAP_SERVER_CONFIG_DIALOG, *PPEAP_SERVER_CONFIG_DIALOG; typedef struct _PEAP_DEFAULT_CRED_DIALOG { PEAP_DEFAULT_CREDENTIALS PeapDefaultCredentials; HWND hWndUserName; HWND hWndPassword; HWND hWndDomain; }PEAP_DEFAULT_CRED_DIALOG, *PPEAP_DEFAULT_CRED_DIALOG; typedef struct _PEAP_INTERACTIVE_UI { DWORD dwEapTypeId; // Embedded Eap Type Id requesting // interactive UI DWORD dwSizeofUIContextData; BYTE bUIContextData[1]; }PEAP_INTERACTIVE_UI, *PPEAP_INTERACTIVE_UI; typedef struct _PEAP_COOKIE_ATTRIBUTE { RAS_AUTH_ATTRIBUTE_TYPE raaType; DWORD dwLength; BYTE Data[1]; }PEAP_COOKIE_ATTRIBUTE, *PPEAP_COOKIE_ATTRIBUTE; typedef struct _PEAP_COOKIE { WCHAR awszIdentity[DNLEN+UNLEN+1]; // Outer Identity that was used for // authentication. DWORD dwNumAuthAttribs; // Number of Ras Auth Attributes // other than MPPE keys // returned when auth succeeded // with full handshake BYTE Data[1]; // Data Conn Props + RAS Auth Attribs }PEAP_COOKIE, *PPEAP_COOKIE; //PEAP Flags #define PEAPCB_FLAG_SERVER 0x00000001 // This is a server #define PEAPCB_FLAG_ROUTER 0x00000002 // This is a router #define PEAPCB_FLAG_NON_INTERACTIVE 0x00000004 // No UI should be displayed #define PEAPCB_FLAG_LOGON 0x00000008 // The user data was // obtained from Winlogon #define PEAPCB_FLAG_PREVIEW 0x00000010 // User has checked // "Prompt for information // before dialing" #define PEAPCB_FLAG_FIRST_LINK 0x00000020 // This is the first link #define PEAPCB_FLAG_MACHINE_AUTH 0x00000040 // Use the default machine cert // or user cert based on the // application logon context #define PEAPCB_FLAG_GUEST_ACCESS 0x00000080 // Request to provide guest // access. #define PEAPCB_FLAG_8021X_AUTH 0x00000100 // Anything specific to 8021x // to be done in TLS #define PEAPCB_VERSION_OK 0x00000200 // version negotiation took place // and all's ok. #define PEAPCB_FAST_ROAMING 0x00000400 // Allow fast roaming typedef struct _PEAP_CONTROL_BLOCK { PEAP_STATE PeapState; //Current Peap State DWORD dwFlags; //Peap Flags HANDLE hTokenImpersonateUser; //Impersonation token. BYTE bId; //Peap Packet Id WCHAR awszIdentity[DNLEN+ UNLEN + 1]; WCHAR awszTypeIdentity[DNLEN+ UNLEN + 1]; WCHAR awszPassword[PWLEN+1]; //Type's password if //send in. BOOL fTlsConnPropDirty; //Need to save the TLS Conn prop EAPTLS_CONN_PROPERTIES_V1 * pNewTlsConnProp; BOOL fEntryConnPropDirty; PPEAP_CONN_PROP pConnProp; //Peap Connection Prop BOOL fTlsUserPropDirty; //Need to saveTLS user prop BOOL fEntryUserPropDirty; DWORD dwAuthResultCode; //Result of authentication BOOL fReceivedTLVSuccessFail; //Received a TLV instead of //a real success or failure BOOL fSendTLVSuccessforFastRoaming; PPP_EAP_PACKET * pPrevReceivePacket; //Previously received packet WORD cbPrevReceivePacket; //Number of bytes in previously //received packet PBYTE pPrevDecData; //Previously Decrypted packet data WORD cbPrevDecData; //Data size // // Encryption related entries in the control block // HCRYPTPROV hProv; //CryptoProvider // // following info is used if we use TLS to do encryption // This is the desired way of doing things since the cipher suite // is negotiated within TLS SecPkgContext_StreamSizes PkgStreamSizes; SecPkgContext_ConnectionInfo PkgConnInfo; PBYTE pbIoBuffer; DWORD dwIoBufferLen; //Enc or Dec Data Length PPEAP_USER_PROP pUserProp; //Peap User Prop RAS_AUTH_ATTRIBUTE * pTlsUserAttributes; //User Attributes send //back by EAPTLS PPEAP_INTERACTIVE_UI pUIContextData; //UI context Data for an eap type BOOL fInvokedInteractiveUI; //PEAP has invoked interactive UI BOOL fExecutingInteractiveUI; EAPTLSCB * pEapTlsCB; //Tls Control Block PPEAP_EAP_INFO pEapInfo; //Eap info - contains all data reqd for //eap type to function well. }PEAPCB, * PPEAPCB; DWORD EapPeapInitialize( IN BOOL fInitialize ); DWORD EapPeapBegin( OUT VOID** ppWorkBuffer, IN PPP_EAP_INPUT* pPppEapInput ); DWORD EapPeapEnd( IN PPEAPCB pPeapCb ); DWORD EapPeapMakeMessage( IN PPEAPCB pPeapCb, IN PPP_EAP_PACKET* pInput, OUT PPP_EAP_PACKET* pOutput, IN DWORD cbSendPacket, OUT PPP_EAP_OUTPUT* pEapOutput, IN PPP_EAP_INPUT* pEapInput ); DWORD EapPeapCMakeMessage( IN PPEAPCB pPeapCb, IN PPP_EAP_PACKET* pReceivePacket, OUT PPP_EAP_PACKET* pSendPacket, IN DWORD cbSendPacket, OUT PPP_EAP_OUTPUT* pEapOutput, IN PPP_EAP_INPUT* pEapInput ); DWORD EapPeapSMakeMessage( IN PPEAPCB pPeapCb, IN PPP_EAP_PACKET* pReceivePacket, OUT PPP_EAP_PACKET* pSendPacket, IN DWORD cbSendPacket, OUT PPP_EAP_OUTPUT* pEapOutput, IN PPP_EAP_INPUT* pEapInput ); //Peap functions from util.c DWORD PeapReadConnectionData( IN BOOL fWireless, IN BYTE* pConnectionDataIn, IN DWORD dwSizeOfConnectionDataIn, OUT PPEAP_CONN_PROP* ppConnProp ); DWORD PeapReadUserData( IN BYTE* pUserDataIn, IN DWORD dwSizeOfUserDataIn, OUT PPEAP_USER_PROP* ppUserProp ); DWORD PeapReDoUserData ( IN DWORD dwNewTypeId, OUT PPEAP_USER_PROP* ppNewUserProp ); DWORD PeapEapInfoAddListNode (PPEAP_EAP_INFO * ppEapInfo); VOID PeapEapInfoFreeList ( PPEAP_EAP_INFO pEapInfo ); DWORD PeapEapInfoExpandSZ (HKEY hkeyPeapType, LPWSTR pwszValue, LPWSTR * ppValueData ); DWORD PeapEapInfoGetList ( LPWSTR lpwszMachineName, PPEAP_EAP_INFO * ppEapInfo); DWORD PeapEapInfoSetConnData ( PPEAP_EAP_INFO pEapInfo, PPEAP_CONN_PROP pPeapConnProp ); DWORD PeapEapInfoInvokeClientConfigUI ( HWND hWndParent, PPEAP_EAP_INFO pEapInfo, DWORD fFlags); DWORD PeapGetFirstEntryConnProp ( PPEAP_CONN_PROP pConnProp, PEAP_ENTRY_CONN_PROPERTIES UNALIGNED ** ppEntryProp ); DWORD PeapGetFirstEntryUserProp ( PPEAP_USER_PROP pUserProp, PEAP_ENTRY_USER_PROPERTIES UNALIGNED ** ppEntryProp ); DWORD PeapEapInfoCopyListNode ( DWORD dwTypeId, PPEAP_EAP_INFO pEapInfoList, PPEAP_EAP_INFO * ppEapInfo ); DWORD PeapEapInfoFindListNode ( DWORD dwTypeId, PPEAP_EAP_INFO pEapInfoList, PPEAP_EAP_INFO * ppEapInfo ); DWORD PeapEapInfoInvokeIdentityUI ( HWND hWndParent, PPEAP_EAP_INFO pEapInfo, const WCHAR * pwszPhoneBook, const WCHAR * pwszEntry, PBYTE pbUserDataIn, DWORD cbUserDataIn, WCHAR** ppwszIdentityOut, DWORD fFlags); #ifdef __cplusplus extern "C" #endif DWORD PeapEapInfoInvokeServerConfigUI ( HWND hWndParent, LPWSTR lpwszMachineName, PPEAP_EAP_INFO pEapInfo ); DWORD OpenPeapRegistryKey( IN WCHAR* pwszMachineName, IN REGSAM samDesired, OUT HKEY* phKeyPeap ); DWORD PeapServerConfigDataIO( IN BOOL fRead, IN WCHAR* pwszMachineName, IN OUT BYTE** ppData, IN DWORD dwNumBytes ); INT_PTR CALLBACK PeapConnDialogProc( IN HWND hWnd, IN UINT unMsg, IN WPARAM wParam, IN LPARAM lParam ); INT_PTR CALLBACK PeapServerDialogProc( IN HWND hWnd, IN UINT unMsg, IN WPARAM wParam, IN LPARAM lParam ); INT_PTR CALLBACK DefaultCredDialogProc( IN HWND hWnd, IN UINT unMsg, IN WPARAM wParam, IN LPARAM lParam ); DWORD GetIdentityFromUserName ( LPWSTR lpszUserName, LPWSTR lpszDomain, LPWSTR * ppwszIdentity ); BOOL FFormatUserIdentity ( LPWSTR lpszUserNameRaw, LPWSTR * lppszUserNameFormatted ); DWORD GetLocalMachineName ( OUT WCHAR ** ppLocalMachineName ); BOOL IsPeapCrippled(HKEY hKeyLM); ///////////////////////////////////////////////////////// // XPSP1 related stuff ///////////////////////////////////////////////////////// HINSTANCE GetResouceDLLHInstance( VOID ); #endif // #ifndef _EAPTLS_H_