]>
Commit | Line | Data |
---|---|---|
099f1b32 AP |
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 | */ | |
853f757e | 21 | /* modified to seed the PRNG */ |
099f1b32 AP |
22 | |
23 | ||
24 | // Include some funky libs I've developed over time | |
25 | ||
26 | #include "CPStringUtils.hpp" | |
27 | #include "ErrorHandling.hpp" | |
28 | #include "MacSocket.h" | |
29 | ||
30 | ||
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! | |
33 | ||
34 | #include <openssl/ssl.h> | |
35 | #include <openssl/err.h> | |
853f757e | 36 | #include <openssl/rand.h> |
099f1b32 | 37 | |
853f757e | 38 | #include <timer.h> |
099f1b32 AP |
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 | ||
52 | ||
53 | ||
54 | ||
55 | // My idle-wait callback. Doesn't do much, does it? Silly cooperative multitasking. | |
56 | ||
57 | OSErr MyMacSocket_IdleWaitCallback(void *inUserRefPtr) | |
58 | { | |
59 | #pragma unused(inUserRefPtr) | |
60 | ||
61 | EventRecord theEvent; | |
62 | ||
63 | ::EventAvail(everyEvent,&theEvent); | |
64 | ||
65 | return(noErr); | |
66 | } | |
67 | ||
68 | ||
69 | ||
70 | // Finally! | |
71 | ||
72 | void main(void) | |
73 | { | |
74 | OSErr errCode; | |
75 | int theSocket = -1; | |
76 | int theTimeout = 30; | |
77 | ||
78 | SSL_CTX *ssl_ctx = nil; | |
79 | SSL *ssl = nil; | |
80 | ||
81 | char tempString[256]; | |
853f757e | 82 | UnsignedWide microTickCount; |
099f1b32 | 83 | |
853f757e BM |
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 | |
86 | ||
099f1b32 AP |
87 | printf("OpenSSL Demo by Roy Wood, roy@centricsystems.ca\n\n"); |
88 | ||
89 | BailIfError(errCode = MacSocket_Startup()); | |
90 | ||
91 | ||
92 | ||
93 | // Create a socket-like object | |
94 | ||
95 | BailIfError(errCode = MacSocket_socket(&theSocket,false,theTimeout * 60,MyMacSocket_IdleWaitCallback,nil)); | |
96 | ||
97 | ||
98 | // Set up the connect string and try to connect | |
99 | ||
100 | CopyCStrAndInsertCStrLongIntIntoCStr("%s:%ld",kHTTPS_DNS,kHTTPS_Port,tempString,sizeof(tempString)); | |
101 | ||
102 | printf("Connecting to %s....\n",tempString); | |
103 | ||
104 | BailIfError(errCode = MacSocket_connect(theSocket,tempString)); | |
105 | ||
106 | ||
107 | // Init SSL stuff | |
108 | ||
109 | SSL_load_error_strings(); | |
110 | ||
111 | SSLeay_add_ssl_algorithms(); | |
112 | ||
113 | ||
114 | // Pick the SSL method | |
115 | ||
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()); | |
119 | ||
120 | ||
853f757e BM |
121 | RAND_seed (seed, sizeof (seed)); |
122 | Microseconds (µTickCount); | |
123 | RAND_add (µTickCount, sizeof (microTickCount), 0); // Entropy is actually > 0, needs an estimate | |
124 | ||
099f1b32 AP |
125 | // Create an SSL thingey and try to negotiate the connection |
126 | ||
127 | ssl = SSL_new(ssl_ctx); | |
128 | ||
129 | SSL_set_fd(ssl,theSocket); | |
130 | ||
131 | errCode = SSL_connect(ssl); | |
132 | ||
133 | if (errCode < 0) | |
134 | { | |
135 | SetErrorMessageAndLongIntAndBail("OpenSSL: Can't initiate SSL connection, SSL_connect() = ",errCode); | |
136 | } | |
137 | ||
138 | // Request the URI from the host | |
139 | ||
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)); | |
143 | ||
144 | ||
145 | errCode = SSL_write(ssl,tempString,CStrLength(tempString)); | |
146 | ||
147 | if (errCode < 0) | |
148 | { | |
149 | SetErrorMessageAndLongIntAndBail("OpenSSL: Error writing data via ssl, SSL_write() = ",errCode); | |
150 | } | |
151 | ||
152 | ||
153 | for (;;) | |
154 | { | |
155 | char tempString[256]; | |
156 | int bytesRead; | |
157 | ||
158 | ||
159 | // Read some bytes and dump them to the console | |
160 | ||
161 | bytesRead = SSL_read(ssl,tempString,sizeof(tempString) - 1); | |
162 | ||
163 | if (bytesRead == 0 && MacSocket_RemoteEndIsClosing(theSocket)) | |
164 | { | |
165 | break; | |
166 | } | |
167 | ||
168 | else if (bytesRead < 0) | |
169 | { | |
170 | SetErrorMessageAndLongIntAndBail("OpenSSL: Error reading data via ssl, SSL_read() = ",bytesRead); | |
171 | } | |
172 | ||
173 | ||
174 | tempString[bytesRead] = '\0'; | |
175 | ||
176 | printf(tempString); | |
177 | } | |
178 | ||
179 | printf("\n\n\n"); | |
180 | ||
181 | // All done! | |
182 | ||
183 | errCode = noErr; | |
184 | ||
185 | ||
186 | EXITPOINT: | |
187 | ||
188 | // Clean up and go home | |
189 | ||
190 | if (theSocket >= 0) | |
191 | { | |
192 | MacSocket_close(theSocket); | |
193 | } | |
194 | ||
195 | if (ssl != nil) | |
196 | { | |
197 | SSL_free(ssl); | |
198 | } | |
199 | ||
200 | if (ssl_ctx != nil) | |
201 | { | |
202 | SSL_CTX_free(ssl_ctx); | |
203 | } | |
204 | ||
205 | ||
206 | if (errCode != noErr) | |
207 | { | |
208 | printf("An error occurred:\n"); | |
209 | ||
210 | printf(GetErrorMessage()); | |
211 | } | |
212 | ||
213 | ||
214 | MacSocket_Shutdown(); | |
215 | } |