1 /*
2 * An demo illustrating how to retrieve a URI from a secure HTTP server.
3 *
4 * Author: Roy Wood
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:
9 *
10 * Macintosh HD:
11 * Development:
12 * OpenSSL-0.9.4:
13 * (OpenSSL sources here)
14 * OpenSSL Example:
15 * (OpenSSL example junk here)
16 *
17 *
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!
20 */
21 /* modified to seed the PRNG */
22 /* modified to use CRandomizer for seeding */
23
24
25 // Include some funky libs I've developed over time
26
27 #include "CPStringUtils.hpp"
28 #include "ErrorHandling.hpp"
29 #include "MacSocket.h"
30 #include "Randomizer.h"
31
32 // We use the OpenSSL implementation of SSL....
33 // This was a lot of work to finally get going, though you wouldn't know it by the results!
34
35 #include <openssl/ssl.h>
36 #include <openssl/err.h>
37
38 #include <timer.h>
39
40 // Let's try grabbing some data from here:
41
42 #define kHTTPS_DNS "www.apache-ssl.org"
43 #define kHTTPS_Port 443
44 #define kHTTPS_URI "/"
45
46
47 // Forward-declare this
48
49 OSErr MyMacSocket_IdleWaitCallback(void *inUserRefPtr);
50
51 // My idle-wait callback. Doesn't do much, does it? Silly cooperative multitasking.
52
MyMacSocket_IdleWaitCallback(void * inUserRefPtr)53 OSErr MyMacSocket_IdleWaitCallback(void *inUserRefPtr)
54 {
55 #pragma unused(inUserRefPtr)
56
57 EventRecord theEvent;
58 ::EventAvail(everyEvent,&theEvent);
59
60 CRandomizer *randomizer = (CRandomizer*)inUserRefPtr;
61 if (randomizer)
62 randomizer->PeriodicAction();
63
64 return(noErr);
65 }
66
67
68 // Finally!
69
main(void)70 void main(void)
71 {
72 OSErr errCode;
73 int theSocket = -1;
74 int theTimeout = 30;
75
76 SSL_CTX *ssl_ctx = nil;
77 SSL *ssl = nil;
78
79 char tempString[256];
80 UnsignedWide microTickCount;
81
82
83 CRandomizer randomizer;
84
85 printf("OpenSSL Demo by Roy Wood, roy@centricsystems.ca\n\n");
86
87 BailIfError(errCode = MacSocket_Startup());
88
89
90
91 // Create a socket-like object
92
93 BailIfError(errCode = MacSocket_socket(&theSocket,false,theTimeout * 60,MyMacSocket_IdleWaitCallback,&randomizer));
94
95
96 // Set up the connect string and try to connect
97
98 CopyCStrAndInsertCStrLongIntIntoCStr("%s:%ld",kHTTPS_DNS,kHTTPS_Port,tempString,sizeof(tempString));
99
100 printf("Connecting to %s....\n",tempString);
101
102 BailIfError(errCode = MacSocket_connect(theSocket,tempString));
103
104
105 // Init SSL stuff
106
107 SSL_load_error_strings();
108
109 SSLeay_add_ssl_algorithms();
110
111
112 // Pick the SSL method
113
114 // ssl_ctx = SSL_CTX_new(SSLv2_client_method());
115 ssl_ctx = SSL_CTX_new(SSLv23_client_method());
116 // ssl_ctx = SSL_CTX_new(SSLv3_client_method());
117
118
119 // Create an SSL thingey and try to negotiate the connection
120
121 ssl = SSL_new(ssl_ctx);
122
123 SSL_set_fd(ssl,theSocket);
124
125 errCode = SSL_connect(ssl);
126
127 if (errCode < 0)
128 {
129 SetErrorMessageAndLongIntAndBail("OpenSSL: Can't initiate SSL connection, SSL_connect() = ",errCode);
130 }
131
132 // Request the URI from the host
133
134 CopyCStrToCStr("GET ",tempString,sizeof(tempString));
135 ConcatCStrToCStr(kHTTPS_URI,tempString,sizeof(tempString));
136 ConcatCStrToCStr(" HTTP/1.0\r\n\r\n",tempString,sizeof(tempString));
137
138
139 errCode = SSL_write(ssl,tempString,CStrLength(tempString));
140
141 if (errCode < 0)
142 {
143 SetErrorMessageAndLongIntAndBail("OpenSSL: Error writing data via ssl, SSL_write() = ",errCode);
144 }
145
146
147 for (;;)
148 {
149 char tempString[256];
150 int bytesRead;
151
152
153 // Read some bytes and dump them to the console
154
155 bytesRead = SSL_read(ssl,tempString,sizeof(tempString) - 1);
156
157 if (bytesRead == 0 && MacSocket_RemoteEndIsClosing(theSocket))
158 {
159 break;
160 }
161
162 else if (bytesRead < 0)
163 {
164 SetErrorMessageAndLongIntAndBail("OpenSSL: Error reading data via ssl, SSL_read() = ",bytesRead);
165 }
166
167
168 tempString[bytesRead] = '\0';
169
170 printf("%s", tempString);
171 }
172
173 printf("\n\n\n");
174
175 // All done!
176
177 errCode = noErr;
178
179
180 EXITPOINT:
181
182 // Clean up and go home
183
184 if (theSocket >= 0)
185 {
186 MacSocket_close(theSocket);
187 }
188
189 if (ssl != nil)
190 {
191 SSL_free(ssl);
192 }
193
194 if (ssl_ctx != nil)
195 {
196 SSL_CTX_free(ssl_ctx);
197 }
198
199
200 if (errCode != noErr)
201 {
202 printf("An error occurred:\n");
203
204 printf("%s",GetErrorMessage());
205 }
206
207
208 MacSocket_Shutdown();
209 }
210