ronys
ronys

Reputation: 518

How to speak SSL from a Windows MFC client?

I've an MFC application that currently uses CAtlHttpClient to query a web server for some information.

I'd like to change this so that the query goes over securely, with server authentication, using SSL.

Googling reveals that Microsoft has changed the way they support this several times, e.g., WinInet, WinHTTP, but for the life of me I can't figure out how to do the above using MFC under MSVS 2005.

The application is in C++, and if at all possible, I'd like to avoid dragging .Net into the picture.

Any help, hints, suggestions or pointers gratefully appreciated!

Thanks,

ony

Upvotes: 2

Views: 4940

Answers (6)

Richard Chambers
Richard Chambers

Reputation: 17643

I am using Visual Studio 2005 with an MFC application that has functionality to access a web site for a small file. I am using the WinINet functions, see the WinINet API reference in Microsoft Windows Dev Center, which provides a simple set of functions that accesses a web site using URL which specifies the protocol (HTTP, HTTPS, FTP, etc.) to pull down a small file.

Looking on the libcurl site there was a reference to this Microsoft Technical Note, Article Id 238425 - INFO: WinInet Not Supported for Use in Services which is marked as retired as of Aug-12-2015. The article summary is:

The Microsoft Win32 Internet Functions (exported from WinInet.dll) are not supported when run from a service or an Internet Information Server (IIS) application (also a service). This article discusses using the WinInet.dll in a service or in Internet Information Server applications.

The applicable source code I am using in my MFC application has a dialog box that uses an HTTPS type URL to which is appended additional information to build a complete URI and then go to the web site to pull the complete small file is:

int GetFile (HINTERNET hOpen, TCHAR * szURL, BYTE  szTemp[4096])   
{
    DWORD dwSize;
    TCHAR szHead[15];
    HINTERNET  hConnect;

    szHead[0] = '\0';
    szTemp[0] = 0;

    // Opens a resource specified by a complete HTTP URL.
    if ( !(hConnect = InternetOpenUrl( hOpen, szURL, szHead, 15, INTERNET_FLAG_DONT_CACHE, 0)))
    {
        DWORD  dwlasterror = GetLastError();
        if (dwlasterror == ERROR_INTERNET_NAME_NOT_RESOLVED) {
            AfxMessageBox (_T("Error: ERROR_INTERNET_NAME_NOT_RESOLVED - check LAN connectivity."));
        } else if (dwlasterror == ERROR_INTERNET_TIMEOUT) {
            AfxMessageBox (_T("Error: ERROR_INTERNET_TIMEOUT - check LAN connectivity."));
        } else if (dwlasterror == ERROR_INTERNET_SERVER_UNREACHABLE) {
            AfxMessageBox (_T("Error: ERROR_INTERNET_SERVER_UNREACHABLE - check LAN connectivity."));
        } else if (dwlasterror == ERROR_INTERNET_OPERATION_CANCELLED) {
            AfxMessageBox (_T("Error: ERROR_INTERNET_OPERATION_CANCELLED - check LAN connectivity."));
        } else {
            CString msg;
            msg.Format (_T("Error: GetLastError() returned %d."), dwlasterror);
            AfxMessageBox (msg);
        }
        return -2;
    }

    // Reads data from a handle opened by the InternetOpenUrl, FtpOpenFile, or HttpOpenRequest function.
    if (InternetReadFile (hConnect, szTemp, 4096,  &dwSize) )
    {
        if (dwSize) {
            return dwSize;
        }
        return -3;
    }
    return -4;
}

int DownloadURLImage (TCHAR * szURL, BYTE  szTemp[4096])
{
    int result = -1;
    HINTERNET hInternet;

    // Initializes an application's use of the WinINet functions.
    hInternet= InternetOpen (_T("DeviceConfig"), INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, NULL);
    if (hInternet) {
        // if open succeeded then get the file and close the handle as we be done.
        result = GetFile (hInternet, szURL, szTemp) ; 
        InternetCloseHandle(hInternet);
    }
    return result ;
}

Upvotes: 0

jussij
jussij

Reputation: 10580

What about using the libeay32.dll and ssleay32.dll files that come as part of OpenSSL:

https://code.google.com/p/openssl-for-windows/

Upvotes: 0

Len Holgate
Len Holgate

Reputation: 21644

Back in 2002 I wrote an article for Windows Developer Magazine that showed how to use OpenSSL to provide SSL for MFC's CAsyncSocket. The code and article are here: http://www.serverframework.com/asynchronousevents/2010/10/using-openssl-with-asynchronous-sockets.html and might help you.You could also do something similar using Microsoft's SChannel but it's a little more involved as OpenSSL does some of the buffering for you so all you need to do is push bytes into it until you get clear text out...

Upvotes: 2

Matt J.
Matt J.

Reputation:

Just use WinHttp, It's a great API and has all you need to do SSL over HTTP (plus works with the Proxy configuration of Vista going forward)

Upvotes: 1

ronys
ronys

Reputation: 518

Found a pointer to some Microsoft sample code which might fit the bill: http://msdn.microsoft.com/en-us/library/s2ya483s(VS.80).aspx

However this fails on AcquireCredentialsHandle, which will be my next question to this august forum...

Upvotes: 2

Rob
Rob

Reputation: 78728

You could take a look at Ultimate TCP/IP - it is MS friendly and might do what you're after:

http://www.codeproject.com/KB/MFC/UltimateTCPIP.aspx

I use this toolkit and it's very good.

Upvotes: 4

Related Questions