GetHTTPS.cpp 4.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 *	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!
 */
21
/* modified to seed the PRNG */
22
/* modified to use CRandomizer for seeding */
23 24 25 26 27 28 29


//	Include some funky libs I've developed over time

#include "CPStringUtils.hpp"
#include "ErrorHandling.hpp"
#include "MacSocket.h"
30
#include "Randomizer.h"
31 32 33 34 35 36 37

//	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>

38
#include <timer.h>
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58

//	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);
59 60 61 62
	
	CRandomizer *randomizer = (CRandomizer*)inUserRefPtr;
	if (randomizer)
		randomizer->PeriodicAction();
63 64 65 66 67 68 69 70 71

	return(noErr);
}


//	Finally!

void main(void)
{
72 73 74
	OSErr				errCode;
	int					theSocket = -1;
	int					theTimeout = 30;
75

76 77
	SSL_CTX				*ssl_ctx = nil;
	SSL					*ssl = nil;
78

79 80
	char				tempString[256];
	UnsignedWide		microTickCount;
81

82 83 84

	CRandomizer randomizer;
	
85 86 87 88 89 90 91 92
	printf("OpenSSL Demo by Roy Wood, roy@centricsystems.ca\n\n");
	
	BailIfError(errCode = MacSocket_Startup());



	//	Create a socket-like object
	
93
	BailIfError(errCode = MacSocket_socket(&theSocket,false,theTimeout * 60,MyMacSocket_IdleWaitCallback,&randomizer));
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209

	
	//	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(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(GetErrorMessage());
	}
	
	
	MacSocket_Shutdown();
}