2 * An demo illustrating how to retrieve a URI from a secure HTTP server.
5 * Date: September 7, 1999
6 * Comments: This relies heavily on my MacSockets library.
7 * This project is also set up so that it expects the OpenSSL source folder (0.9.4 as I write this)
8 * to live in a folder called "OpenSSL-0.9.4" in this project's parent folder. For example:
13 * (OpenSSL sources here)
15 * (OpenSSL example junk here)
18 * Also-- before attempting to compile this, make sure the aliases in "OpenSSL-0.9.4:include:openssl"
19 * are installed! Use the AppleScript applet in the "openssl-0.9.4" folder to do this!
21 /* modified to seed the PRNG */
24 // Include some funky libs I've developed over time
26 #include "CPStringUtils.hpp"
27 #include "ErrorHandling.hpp"
28 #include "MacSocket.h"
31 // We use the OpenSSL implementation of SSL....
32 // This was a lot of work to finally get going, though you wouldn't know it by the results!
34 #include <openssl/ssl.h>
35 #include <openssl/err.h>
36 #include <openssl/rand.h>
40 // Let's try grabbing some data from here:
42 #define kHTTPS_DNS "www.apache-ssl.org"
43 #define kHTTPS_Port 443
44 #define kHTTPS_URI "/"
47 // Forward-declare this
49 OSErr MyMacSocket_IdleWaitCallback(void *inUserRefPtr);
55 // My idle-wait callback. Doesn't do much, does it? Silly cooperative multitasking.
57 OSErr MyMacSocket_IdleWaitCallback(void *inUserRefPtr)
59 #pragma unused(inUserRefPtr)
63 ::EventAvail(everyEvent,&theEvent);
78 SSL_CTX *ssl_ctx = nil;
82 UnsignedWide microTickCount;
84 #warning -- USE A TRUE RANDOM SEED, AND ADD ENTROPY WHENEVER POSSIBLE. --
85 const char seed[] = "uyq9,7-b(VHGT^%$&^F/,876;,;./lkJHGFUY{PO*"; // Just gobbledygook
87 printf("OpenSSL Demo by Roy Wood, roy@centricsystems.ca\n\n");
89 BailIfError(errCode = MacSocket_Startup());
93 // Create a socket-like object
95 BailIfError(errCode = MacSocket_socket(&theSocket,false,theTimeout * 60,MyMacSocket_IdleWaitCallback,nil));
98 // Set up the connect string and try to connect
100 CopyCStrAndInsertCStrLongIntIntoCStr("%s:%ld",kHTTPS_DNS,kHTTPS_Port,tempString,sizeof(tempString));
102 printf("Connecting to %s....\n",tempString);
104 BailIfError(errCode = MacSocket_connect(theSocket,tempString));
109 SSL_load_error_strings();
111 SSLeay_add_ssl_algorithms();
114 // Pick the SSL method
116 // ssl_ctx = SSL_CTX_new(SSLv2_client_method());
117 ssl_ctx = SSL_CTX_new(SSLv23_client_method());
118 // ssl_ctx = SSL_CTX_new(SSLv3_client_method());
121 RAND_seed (seed, sizeof (seed));
122 Microseconds (µTickCount);
123 RAND_add (µTickCount, sizeof (microTickCount), 0); // Entropy is actually > 0, needs an estimate
125 // Create an SSL thingey and try to negotiate the connection
127 ssl = SSL_new(ssl_ctx);
129 SSL_set_fd(ssl,theSocket);
131 errCode = SSL_connect(ssl);
135 SetErrorMessageAndLongIntAndBail("OpenSSL: Can't initiate SSL connection, SSL_connect() = ",errCode);
138 // Request the URI from the host
140 CopyCStrToCStr("GET ",tempString,sizeof(tempString));
141 ConcatCStrToCStr(kHTTPS_URI,tempString,sizeof(tempString));
142 ConcatCStrToCStr(" HTTP/1.0\r\n\r\n",tempString,sizeof(tempString));
145 errCode = SSL_write(ssl,tempString,CStrLength(tempString));
149 SetErrorMessageAndLongIntAndBail("OpenSSL: Error writing data via ssl, SSL_write() = ",errCode);
155 char tempString[256];
159 // Read some bytes and dump them to the console
161 bytesRead = SSL_read(ssl,tempString,sizeof(tempString) - 1);
163 if (bytesRead == 0 && MacSocket_RemoteEndIsClosing(theSocket))
168 else if (bytesRead < 0)
170 SetErrorMessageAndLongIntAndBail("OpenSSL: Error reading data via ssl, SSL_read() = ",bytesRead);
174 tempString[bytesRead] = '\0';
188 // Clean up and go home
192 MacSocket_close(theSocket);
202 SSL_CTX_free(ssl_ctx);
206 if (errCode != noErr)
208 printf("An error occurred:\n");
210 printf(GetErrorMessage());
214 MacSocket_Shutdown();