Allow for higher granularity of entropy estimates by using 'double'
[openssl.git] / MacOS / GetHTTPS.src / GetHTTPS.cpp
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
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>
36 #include <openssl/rand.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
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];
82 UnsignedWide            microTickCount;
83         
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
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
121         RAND_seed (seed, sizeof (seed));
122         Microseconds (&microTickCount);
123         RAND_add (&microTickCount, sizeof (microTickCount), 0);         // Entropy is actually > 0, needs an estimate
124
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 }