210 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			210 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/*
 | 
						|
 *	An demo illustrating how to retrieve a URI from a secure HTTP server.
 | 
						|
 *
 | 
						|
 *	Author: 	Roy Wood
 | 
						|
 *	Date:		September 7, 1999
 | 
						|
 *	Comments:	This relies heavily on my MacSockets library.
 | 
						|
 *				This project is also set up so that it expects the OpenSSL source folder (0.9.4 as I write this)
 | 
						|
 *				to live in a folder called "OpenSSL-0.9.4" in this project's parent folder.  For example:
 | 
						|
 *
 | 
						|
 *					Macintosh HD:
 | 
						|
 *						Development:
 | 
						|
 *							OpenSSL-0.9.4:
 | 
						|
 *								(OpenSSL sources here)
 | 
						|
 *							OpenSSL Example:
 | 
						|
 *								(OpenSSL example junk here)
 | 
						|
 *
 | 
						|
 *
 | 
						|
 *				Also-- before attempting to compile this, make sure the aliases in "OpenSSL-0.9.4:include:openssl" 
 | 
						|
 *				are installed!  Use the AppleScript applet in the "openssl-0.9.4" folder to do this!
 | 
						|
 */
 | 
						|
/* modified to seed the PRNG */
 | 
						|
/* modified to use CRandomizer for seeding */
 | 
						|
 | 
						|
 | 
						|
//	Include some funky libs I've developed over time
 | 
						|
 | 
						|
#include "CPStringUtils.hpp"
 | 
						|
#include "ErrorHandling.hpp"
 | 
						|
#include "MacSocket.h"
 | 
						|
#include "Randomizer.h"
 | 
						|
 | 
						|
//	We use the OpenSSL implementation of SSL....
 | 
						|
//	This was a lot of work to finally get going, though you wouldn't know it by the results!
 | 
						|
 | 
						|
#include <openssl/ssl.h>
 | 
						|
#include <openssl/err.h>
 | 
						|
 | 
						|
#include <timer.h>
 | 
						|
 | 
						|
//	Let's try grabbing some data from here:
 | 
						|
 | 
						|
#define kHTTPS_DNS		"www.apache-ssl.org"
 | 
						|
#define kHTTPS_Port		443
 | 
						|
#define kHTTPS_URI		"/"
 | 
						|
 | 
						|
 | 
						|
//	Forward-declare this
 | 
						|
 | 
						|
OSErr MyMacSocket_IdleWaitCallback(void *inUserRefPtr);
 | 
						|
 | 
						|
//	My idle-wait callback.  Doesn't do much, does it?  Silly cooperative multitasking.
 | 
						|
 | 
						|
OSErr MyMacSocket_IdleWaitCallback(void *inUserRefPtr)
 | 
						|
{
 | 
						|
#pragma unused(inUserRefPtr)
 | 
						|
 | 
						|
EventRecord		theEvent;
 | 
						|
	::EventAvail(everyEvent,&theEvent);
 | 
						|
	
 | 
						|
	CRandomizer *randomizer = (CRandomizer*)inUserRefPtr;
 | 
						|
	if (randomizer)
 | 
						|
		randomizer->PeriodicAction();
 | 
						|
 | 
						|
	return(noErr);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
//	Finally!
 | 
						|
 | 
						|
void main(void)
 | 
						|
{
 | 
						|
	OSErr				errCode;
 | 
						|
	int					theSocket = -1;
 | 
						|
	int					theTimeout = 30;
 | 
						|
 | 
						|
	SSL_CTX				*ssl_ctx = nil;
 | 
						|
	SSL					*ssl = nil;
 | 
						|
 | 
						|
	char				tempString[256];
 | 
						|
	UnsignedWide		microTickCount;
 | 
						|
 | 
						|
 | 
						|
	CRandomizer randomizer;
 | 
						|
	
 | 
						|
	printf("OpenSSL Demo by Roy Wood, roy@centricsystems.ca\n\n");
 | 
						|
	
 | 
						|
	BailIfError(errCode = MacSocket_Startup());
 | 
						|
 | 
						|
 | 
						|
 | 
						|
	//	Create a socket-like object
 | 
						|
	
 | 
						|
	BailIfError(errCode = MacSocket_socket(&theSocket,false,theTimeout * 60,MyMacSocket_IdleWaitCallback,&randomizer));
 | 
						|
 | 
						|
	
 | 
						|
	//	Set up the connect string and try to connect
 | 
						|
	
 | 
						|
	CopyCStrAndInsertCStrLongIntIntoCStr("%s:%ld",kHTTPS_DNS,kHTTPS_Port,tempString,sizeof(tempString));
 | 
						|
	
 | 
						|
	printf("Connecting to %s....\n",tempString);
 | 
						|
 | 
						|
	BailIfError(errCode = MacSocket_connect(theSocket,tempString));
 | 
						|
	
 | 
						|
	
 | 
						|
	//	Init SSL stuff
 | 
						|
	
 | 
						|
	SSL_load_error_strings();
 | 
						|
	
 | 
						|
	SSLeay_add_ssl_algorithms();
 | 
						|
	
 | 
						|
	
 | 
						|
	//	Pick the SSL method
 | 
						|
	
 | 
						|
//	ssl_ctx = SSL_CTX_new(SSLv2_client_method());
 | 
						|
	ssl_ctx = SSL_CTX_new(SSLv23_client_method());
 | 
						|
//	ssl_ctx = SSL_CTX_new(SSLv3_client_method());
 | 
						|
			
 | 
						|
 | 
						|
	//	Create an SSL thingey and try to negotiate the connection
 | 
						|
	
 | 
						|
	ssl = SSL_new(ssl_ctx);
 | 
						|
	
 | 
						|
	SSL_set_fd(ssl,theSocket);
 | 
						|
	
 | 
						|
	errCode = SSL_connect(ssl);
 | 
						|
	
 | 
						|
	if (errCode < 0)
 | 
						|
	{
 | 
						|
		SetErrorMessageAndLongIntAndBail("OpenSSL: Can't initiate SSL connection, SSL_connect() = ",errCode);
 | 
						|
	}
 | 
						|
	
 | 
						|
	//	Request the URI from the host
 | 
						|
	
 | 
						|
	CopyCStrToCStr("GET ",tempString,sizeof(tempString));
 | 
						|
	ConcatCStrToCStr(kHTTPS_URI,tempString,sizeof(tempString));
 | 
						|
	ConcatCStrToCStr(" HTTP/1.0\r\n\r\n",tempString,sizeof(tempString));
 | 
						|
 | 
						|
	
 | 
						|
	errCode = SSL_write(ssl,tempString,CStrLength(tempString));
 | 
						|
	
 | 
						|
	if (errCode < 0)
 | 
						|
	{
 | 
						|
		SetErrorMessageAndLongIntAndBail("OpenSSL: Error writing data via ssl, SSL_write() = ",errCode);
 | 
						|
	}
 | 
						|
	
 | 
						|
 | 
						|
	for (;;)
 | 
						|
	{
 | 
						|
	char	tempString[256];
 | 
						|
	int		bytesRead;
 | 
						|
		
 | 
						|
 | 
						|
		//	Read some bytes and dump them to the console
 | 
						|
		
 | 
						|
		bytesRead = SSL_read(ssl,tempString,sizeof(tempString) - 1);
 | 
						|
		
 | 
						|
		if (bytesRead == 0 && MacSocket_RemoteEndIsClosing(theSocket))
 | 
						|
		{
 | 
						|
			break;
 | 
						|
		}
 | 
						|
		
 | 
						|
		else if (bytesRead < 0)
 | 
						|
		{
 | 
						|
			SetErrorMessageAndLongIntAndBail("OpenSSL: Error reading data via ssl, SSL_read() = ",bytesRead);
 | 
						|
		}
 | 
						|
		
 | 
						|
		
 | 
						|
		tempString[bytesRead] = '\0';
 | 
						|
		
 | 
						|
		printf("%s", tempString);
 | 
						|
	}
 | 
						|
	
 | 
						|
	printf("\n\n\n");
 | 
						|
	
 | 
						|
	//	All done!
 | 
						|
	
 | 
						|
	errCode = noErr;
 | 
						|
	
 | 
						|
	
 | 
						|
EXITPOINT:
 | 
						|
 | 
						|
	//	Clean up and go home
 | 
						|
	
 | 
						|
	if (theSocket >= 0)
 | 
						|
	{
 | 
						|
		MacSocket_close(theSocket);
 | 
						|
	}
 | 
						|
	
 | 
						|
	if (ssl != nil)
 | 
						|
	{
 | 
						|
		SSL_free(ssl);
 | 
						|
	}
 | 
						|
	
 | 
						|
	if (ssl_ctx != nil)
 | 
						|
	{
 | 
						|
		SSL_CTX_free(ssl_ctx);
 | 
						|
	}
 | 
						|
	
 | 
						|
	
 | 
						|
	if (errCode != noErr)
 | 
						|
	{
 | 
						|
		printf("An error occurred:\n");
 | 
						|
		
 | 
						|
		printf("%s",GetErrorMessage());
 | 
						|
	}
 | 
						|
	
 | 
						|
	
 | 
						|
	MacSocket_Shutdown();
 | 
						|
}
 |