diff options
author | Brent Cook <bcook@openbsd.org> | 2015-09-12 07:48:06 -0500 |
---|---|---|
committer | Brent Cook <bcook@openbsd.org> | 2015-09-12 08:08:24 -0500 |
commit | 854f4f69af9003c0c29d3838001f549beaf36936 (patch) | |
tree | 913e183b140e6a974efa7643ec217d0f6d574257 /apps/openssl | |
parent | 34bfb6ecb5d178ee62b402ee344d0f6caf5cdad0 (diff) | |
download | portable-854f4f69af9003c0c29d3838001f549beaf36936.tar.gz portable-854f4f69af9003c0c29d3838001f549beaf36936.tar.bz2 portable-854f4f69af9003c0c29d3838001f549beaf36936.zip |
add 'nc' to the distribution as an example of libtls client and server
Diffstat (limited to 'apps/openssl')
-rw-r--r-- | apps/openssl/Makefile.am | 116 | ||||
-rw-r--r-- | apps/openssl/compat/apps_win.c | 29 | ||||
-rw-r--r-- | apps/openssl/compat/certhash_win.c | 13 | ||||
-rw-r--r-- | apps/openssl/compat/poll_win.c | 327 |
4 files changed, 485 insertions, 0 deletions
diff --git a/apps/openssl/Makefile.am b/apps/openssl/Makefile.am new file mode 100644 index 0000000..9c763e1 --- /dev/null +++ b/apps/openssl/Makefile.am | |||
@@ -0,0 +1,116 @@ | |||
1 | include $(top_srcdir)/Makefile.am.common | ||
2 | |||
3 | bin_PROGRAMS = openssl | ||
4 | |||
5 | openssl_LDADD = $(PLATFORM_LDADD) $(PROG_LDADD) | ||
6 | openssl_LDADD += $(top_builddir)/ssl/libssl.la | ||
7 | openssl_LDADD += $(top_builddir)/crypto/libcrypto.la | ||
8 | |||
9 | openssl_SOURCES = apps.c | ||
10 | openssl_SOURCES += asn1pars.c | ||
11 | openssl_SOURCES += ca.c | ||
12 | openssl_SOURCES += ciphers.c | ||
13 | openssl_SOURCES += cms.c | ||
14 | openssl_SOURCES += crl.c | ||
15 | openssl_SOURCES += crl2p7.c | ||
16 | openssl_SOURCES += dgst.c | ||
17 | openssl_SOURCES += dh.c | ||
18 | openssl_SOURCES += dhparam.c | ||
19 | openssl_SOURCES += dsa.c | ||
20 | openssl_SOURCES += dsaparam.c | ||
21 | openssl_SOURCES += ec.c | ||
22 | openssl_SOURCES += ecparam.c | ||
23 | openssl_SOURCES += enc.c | ||
24 | openssl_SOURCES += errstr.c | ||
25 | openssl_SOURCES += gendh.c | ||
26 | openssl_SOURCES += gendsa.c | ||
27 | openssl_SOURCES += genpkey.c | ||
28 | openssl_SOURCES += genrsa.c | ||
29 | openssl_SOURCES += nseq.c | ||
30 | openssl_SOURCES += ocsp.c | ||
31 | openssl_SOURCES += openssl.c | ||
32 | openssl_SOURCES += passwd.c | ||
33 | openssl_SOURCES += pkcs12.c | ||
34 | openssl_SOURCES += pkcs7.c | ||
35 | openssl_SOURCES += pkcs8.c | ||
36 | openssl_SOURCES += pkey.c | ||
37 | openssl_SOURCES += pkeyparam.c | ||
38 | openssl_SOURCES += pkeyutl.c | ||
39 | openssl_SOURCES += prime.c | ||
40 | openssl_SOURCES += rand.c | ||
41 | openssl_SOURCES += req.c | ||
42 | openssl_SOURCES += rsa.c | ||
43 | openssl_SOURCES += rsautl.c | ||
44 | openssl_SOURCES += s_cb.c | ||
45 | openssl_SOURCES += s_client.c | ||
46 | openssl_SOURCES += s_server.c | ||
47 | openssl_SOURCES += s_socket.c | ||
48 | openssl_SOURCES += s_time.c | ||
49 | openssl_SOURCES += sess_id.c | ||
50 | openssl_SOURCES += smime.c | ||
51 | openssl_SOURCES += speed.c | ||
52 | openssl_SOURCES += spkac.c | ||
53 | openssl_SOURCES += ts.c | ||
54 | openssl_SOURCES += verify.c | ||
55 | openssl_SOURCES += version.c | ||
56 | openssl_SOURCES += x509.c | ||
57 | |||
58 | if BUILD_CERTHASH | ||
59 | openssl_SOURCES += certhash.c | ||
60 | else | ||
61 | openssl_SOURCES += compat/certhash_win.c | ||
62 | endif | ||
63 | |||
64 | if HOST_WIN | ||
65 | openssl_SOURCES += compat/apps_win.c | ||
66 | else | ||
67 | openssl_SOURCES += apps_posix.c | ||
68 | endif | ||
69 | |||
70 | if !HAVE_POLL | ||
71 | if HOST_WIN | ||
72 | openssl_SOURCES += compat/poll_win.c | ||
73 | endif | ||
74 | endif | ||
75 | |||
76 | if !HAVE_STRTONUM | ||
77 | openssl_SOURCES += compat/strtonum.c | ||
78 | endif | ||
79 | |||
80 | noinst_HEADERS = apps.h | ||
81 | noinst_HEADERS += progs.h | ||
82 | noinst_HEADERS += s_apps.h | ||
83 | noinst_HEADERS += testdsa.h | ||
84 | noinst_HEADERS += testrsa.h | ||
85 | noinst_HEADERS += timeouts.h | ||
86 | |||
87 | EXTRA_DIST = cert.pem | ||
88 | EXTRA_DIST += openssl.cnf | ||
89 | EXTRA_DIST += x509v3.cnf | ||
90 | |||
91 | install-exec-hook: | ||
92 | @if [ "@OPENSSLDIR@x" != "x" ]; then \ | ||
93 | OPENSSLDIR="$(DESTDIR)/@OPENSSLDIR@"; \ | ||
94 | else \ | ||
95 | OPENSSLDIR="$(DESTDIR)/$(sysconfdir)/ssl"; \ | ||
96 | fi; \ | ||
97 | mkdir -p "$$OPENSSLDIR/certs"; \ | ||
98 | for i in cert.pem openssl.cnf x509v3.cnf; do \ | ||
99 | if [ ! -f "$$OPENSSLDIR/$i" ]; then \ | ||
100 | $(INSTALL) -m 644 "$(srcdir)/$$i" "$$OPENSSLDIR/$$i"; \ | ||
101 | else \ | ||
102 | echo " $$OPENSSLDIR/$$i already exists, install will not overwrite"; \ | ||
103 | fi \ | ||
104 | done | ||
105 | |||
106 | uninstall-local: | ||
107 | @if [ "@OPENSSLDIR@x" != "x" ]; then \ | ||
108 | OPENSSLDIR="$(DESTDIR)/@OPENSSLDIR@"; \ | ||
109 | else \ | ||
110 | OPENSSLDIR="$(DESTDIR)/$(sysconfdir)/ssl"; \ | ||
111 | fi; \ | ||
112 | for i in cert.pem openssl.cnf x509v3.cnf; do \ | ||
113 | if cmp -s "$$OPENSSLDIR/$$i" "$(srcdir)/$$i"; then \ | ||
114 | rm -f "$$OPENSSLDIR/$$i"; \ | ||
115 | fi \ | ||
116 | done | ||
diff --git a/apps/openssl/compat/apps_win.c b/apps/openssl/compat/apps_win.c new file mode 100644 index 0000000..496ac03 --- /dev/null +++ b/apps/openssl/compat/apps_win.c | |||
@@ -0,0 +1,29 @@ | |||
1 | /* | ||
2 | * Public domain | ||
3 | * | ||
4 | * Dongsheng Song <dongsheng.song@gmail.com> | ||
5 | * Brent Cook <bcook@openbsd.org> | ||
6 | */ | ||
7 | |||
8 | #include <windows.h> | ||
9 | |||
10 | #include "apps.h" | ||
11 | |||
12 | double | ||
13 | app_tminterval(int stop, int usertime) | ||
14 | { | ||
15 | static unsigned __int64 tmstart; | ||
16 | union { | ||
17 | unsigned __int64 u64; | ||
18 | FILETIME ft; | ||
19 | } ct, et, kt, ut; | ||
20 | |||
21 | GetProcessTimes(GetCurrentProcess(), &ct.ft, &et.ft, &kt.ft, &ut.ft); | ||
22 | |||
23 | if (stop == TM_START) { | ||
24 | tmstart = ut.u64 + kt.u64; | ||
25 | } else { | ||
26 | return (ut.u64 + kt.u64 - tmstart) / (double) 10000000; | ||
27 | } | ||
28 | return 0; | ||
29 | } | ||
diff --git a/apps/openssl/compat/certhash_win.c b/apps/openssl/compat/certhash_win.c new file mode 100644 index 0000000..8238ff7 --- /dev/null +++ b/apps/openssl/compat/certhash_win.c | |||
@@ -0,0 +1,13 @@ | |||
1 | /* | ||
2 | * Public domain | ||
3 | * certhash dummy implementation for platforms without symlinks | ||
4 | */ | ||
5 | |||
6 | #include "apps.h" | ||
7 | |||
8 | int | ||
9 | certhash_main(int argc, char **argv) | ||
10 | { | ||
11 | fprintf(stderr, "certhash is not enabled on this platform\n"); | ||
12 | return (1); | ||
13 | } | ||
diff --git a/apps/openssl/compat/poll_win.c b/apps/openssl/compat/poll_win.c new file mode 100644 index 0000000..ce47b01 --- /dev/null +++ b/apps/openssl/compat/poll_win.c | |||
@@ -0,0 +1,327 @@ | |||
1 | /* | ||
2 | * Public domain | ||
3 | * | ||
4 | * poll(2) emulation for Windows | ||
5 | * | ||
6 | * This emulates just-enough poll functionality on Windows to work in the | ||
7 | * context of the openssl(1) program. This is not a replacement for | ||
8 | * POSIX.1-2001 poll(2), though it may come closer than I care to admit. | ||
9 | * | ||
10 | * Dongsheng Song <dongsheng.song@gmail.com> | ||
11 | * Brent Cook <bcook@openbsd.org> | ||
12 | */ | ||
13 | |||
14 | #include <conio.h> | ||
15 | #include <errno.h> | ||
16 | #include <io.h> | ||
17 | #include <poll.h> | ||
18 | #include <ws2tcpip.h> | ||
19 | |||
20 | static int | ||
21 | conn_is_closed(int fd) | ||
22 | { | ||
23 | char buf[1]; | ||
24 | int ret = recv(fd, buf, 1, MSG_PEEK); | ||
25 | if (ret == -1) { | ||
26 | switch (WSAGetLastError()) { | ||
27 | case WSAECONNABORTED: | ||
28 | case WSAECONNRESET: | ||
29 | case WSAENETRESET: | ||
30 | case WSAESHUTDOWN: | ||
31 | return 1; | ||
32 | } | ||
33 | } | ||
34 | return 0; | ||
35 | } | ||
36 | |||
37 | static int | ||
38 | conn_has_oob_data(int fd) | ||
39 | { | ||
40 | char buf[1]; | ||
41 | return (recv(fd, buf, 1, MSG_PEEK | MSG_OOB) == 1); | ||
42 | } | ||
43 | |||
44 | static int | ||
45 | is_socket(int fd) | ||
46 | { | ||
47 | if (fd < 3) | ||
48 | return 0; | ||
49 | WSANETWORKEVENTS events; | ||
50 | return (WSAEnumNetworkEvents((SOCKET)fd, NULL, &events) == 0); | ||
51 | } | ||
52 | |||
53 | static int | ||
54 | compute_select_revents(int fd, short events, | ||
55 | fd_set *rfds, fd_set *wfds, fd_set *efds) | ||
56 | { | ||
57 | int rc = 0; | ||
58 | |||
59 | if ((events & (POLLIN | POLLRDNORM | POLLRDBAND)) && | ||
60 | FD_ISSET(fd, rfds)) { | ||
61 | if (conn_is_closed(fd)) | ||
62 | rc |= POLLHUP; | ||
63 | else | ||
64 | rc |= POLLIN | POLLRDNORM; | ||
65 | } | ||
66 | |||
67 | if ((events & (POLLOUT | POLLWRNORM | POLLWRBAND)) && | ||
68 | FD_ISSET(fd, wfds)) | ||
69 | rc |= POLLOUT; | ||
70 | |||
71 | if (FD_ISSET(fd, efds)) { | ||
72 | if (conn_is_closed(fd)) | ||
73 | rc |= POLLHUP; | ||
74 | else if (conn_has_oob_data(fd)) | ||
75 | rc |= POLLRDBAND | POLLPRI; | ||
76 | } | ||
77 | |||
78 | return rc; | ||
79 | } | ||
80 | |||
81 | static int | ||
82 | compute_wait_revents(HANDLE h, short events, int object, int wait_rc) | ||
83 | { | ||
84 | int rc = 0; | ||
85 | INPUT_RECORD record; | ||
86 | DWORD num_read; | ||
87 | |||
88 | /* | ||
89 | * Assume we can always write to file handles (probably a bad | ||
90 | * assumption but works for now, at least it doesn't block). | ||
91 | */ | ||
92 | if (events & (POLLOUT | POLLWRNORM)) | ||
93 | rc |= POLLOUT; | ||
94 | |||
95 | /* | ||
96 | * Check if this handle was signaled by WaitForMultipleObjects | ||
97 | */ | ||
98 | if (wait_rc >= WAIT_OBJECT_0 && (object == (wait_rc - WAIT_OBJECT_0)) | ||
99 | && (events & (POLLIN | POLLRDNORM))) { | ||
100 | |||
101 | /* | ||
102 | * Check if this file is stdin, and if so, if it is a console. | ||
103 | */ | ||
104 | if (h == GetStdHandle(STD_INPUT_HANDLE) && | ||
105 | PeekConsoleInput(h, &record, 1, &num_read) == 1) { | ||
106 | |||
107 | /* | ||
108 | * Handle the input console buffer differently, | ||
109 | * since it can signal on other events like | ||
110 | * window and mouse, but read can still block. | ||
111 | */ | ||
112 | if (record.EventType == KEY_EVENT && | ||
113 | record.Event.KeyEvent.bKeyDown) { | ||
114 | rc |= POLLIN; | ||
115 | } else { | ||
116 | /* | ||
117 | * Flush non-character events from the | ||
118 | * console buffer. | ||
119 | */ | ||
120 | ReadConsoleInput(h, &record, 1, &num_read); | ||
121 | } | ||
122 | } else { | ||
123 | rc |= POLLIN; | ||
124 | } | ||
125 | } | ||
126 | |||
127 | return rc; | ||
128 | } | ||
129 | |||
130 | static int | ||
131 | wsa_select_errno(int err) | ||
132 | { | ||
133 | switch (err) { | ||
134 | case WSAEINTR: | ||
135 | case WSAEINPROGRESS: | ||
136 | errno = EINTR; | ||
137 | break; | ||
138 | case WSAEFAULT: | ||
139 | /* | ||
140 | * Windows uses WSAEFAULT for both resource allocation failures | ||
141 | * and arguments not being contained in the user's address | ||
142 | * space. So, we have to choose EFAULT or ENOMEM. | ||
143 | */ | ||
144 | errno = EFAULT; | ||
145 | break; | ||
146 | case WSAEINVAL: | ||
147 | errno = EINVAL; | ||
148 | break; | ||
149 | case WSANOTINITIALISED: | ||
150 | errno = EPERM; | ||
151 | break; | ||
152 | case WSAENETDOWN: | ||
153 | errno = ENOMEM; | ||
154 | break; | ||
155 | } | ||
156 | return -1; | ||
157 | } | ||
158 | |||
159 | int | ||
160 | poll(struct pollfd *pfds, nfds_t nfds, int timeout_ms) | ||
161 | { | ||
162 | nfds_t i; | ||
163 | int timespent_ms, looptime_ms; | ||
164 | |||
165 | /* | ||
166 | * select machinery | ||
167 | */ | ||
168 | fd_set rfds, wfds, efds; | ||
169 | int rc; | ||
170 | int num_sockets; | ||
171 | |||
172 | /* | ||
173 | * wait machinery | ||
174 | */ | ||
175 | DWORD wait_rc; | ||
176 | HANDLE handles[FD_SETSIZE]; | ||
177 | int num_handles; | ||
178 | |||
179 | if (pfds == NULL) { | ||
180 | errno = EINVAL; | ||
181 | return -1; | ||
182 | } | ||
183 | |||
184 | if (nfds <= 0) { | ||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | FD_ZERO(&rfds); | ||
189 | FD_ZERO(&wfds); | ||
190 | FD_ZERO(&efds); | ||
191 | num_sockets = 0; | ||
192 | num_handles = 0; | ||
193 | |||
194 | for (i = 0; i < nfds; i++) { | ||
195 | if ((int)pfds[i].fd < 0) | ||
196 | continue; | ||
197 | |||
198 | if (is_socket(pfds[i].fd)) { | ||
199 | if (num_sockets >= FD_SETSIZE) { | ||
200 | errno = EINVAL; | ||
201 | return -1; | ||
202 | } | ||
203 | |||
204 | FD_SET(pfds[i].fd, &efds); | ||
205 | |||
206 | if (pfds[i].events & | ||
207 | (POLLIN | POLLRDNORM | POLLRDBAND)) { | ||
208 | FD_SET(pfds[i].fd, &rfds); | ||
209 | } | ||
210 | |||
211 | if (pfds[i].events & | ||
212 | (POLLOUT | POLLWRNORM | POLLWRBAND)) { | ||
213 | FD_SET(pfds[i].fd, &wfds); | ||
214 | } | ||
215 | num_sockets++; | ||
216 | |||
217 | } else { | ||
218 | if (num_handles >= FD_SETSIZE) { | ||
219 | errno = EINVAL; | ||
220 | return -1; | ||
221 | } | ||
222 | |||
223 | handles[num_handles++] = | ||
224 | (HANDLE)_get_osfhandle(pfds[i].fd); | ||
225 | } | ||
226 | } | ||
227 | |||
228 | /* | ||
229 | * Determine if the files, pipes, sockets, consoles, etc. have signaled. | ||
230 | * | ||
231 | * Do this by alternating a loop between WaitForMultipleObjects for | ||
232 | * non-sockets and and select for sockets. | ||
233 | * | ||
234 | * I tried to implement this all in terms of WaitForMultipleObjects | ||
235 | * with a select-based 'poll' of the sockets at the end to get extra | ||
236 | * specific socket status. | ||
237 | * | ||
238 | * However, the cost of setting up an event handle for each socket and | ||
239 | * cleaning them up reliably was pretty high. Since the event handle | ||
240 | * associated with a socket is also global, creating a new one here | ||
241 | * cancels one that may exist externally to this function. | ||
242 | * | ||
243 | * At any rate, even if global socket event handles were not an issue, | ||
244 | * the 'FD_WRITE' status of a socket event handle does not behave in an | ||
245 | * expected fashion, being triggered by an edge on a write buffer rather | ||
246 | * than simply triggering if there is space available. | ||
247 | */ | ||
248 | timespent_ms = 0; | ||
249 | wait_rc = WAIT_FAILED; | ||
250 | |||
251 | if (timeout_ms < 0) | ||
252 | timeout_ms = INFINITE; | ||
253 | looptime_ms = timeout_ms > 100 ? 100 : timeout_ms; | ||
254 | |||
255 | do { | ||
256 | struct timeval tv = {0, looptime_ms * 1000}; | ||
257 | int handle_signaled = 0; | ||
258 | |||
259 | /* | ||
260 | * Check if any file handles have signaled | ||
261 | */ | ||
262 | if (num_handles) { | ||
263 | wait_rc = WaitForMultipleObjects(num_handles, handles, | ||
264 | FALSE, 0); | ||
265 | if (wait_rc == WAIT_FAILED) { | ||
266 | /* | ||
267 | * The documentation for WaitForMultipleObjects | ||
268 | * does not specify what values GetLastError | ||
269 | * may return here. Rather than enumerate | ||
270 | * badness like for wsa_select_errno, assume a | ||
271 | * general errno value. | ||
272 | */ | ||
273 | errno = ENOMEM; | ||
274 | return 0; | ||
275 | } | ||
276 | } | ||
277 | |||
278 | /* | ||
279 | * If we signaled on a file handle, don't wait on the sockets. | ||
280 | */ | ||
281 | if (wait_rc >= WAIT_OBJECT_0 && | ||
282 | (wait_rc <= WAIT_OBJECT_0 + num_handles - 1)) { | ||
283 | tv.tv_usec = 0; | ||
284 | handle_signaled = 1; | ||
285 | } | ||
286 | |||
287 | /* | ||
288 | * Check if any sockets have signaled | ||
289 | */ | ||
290 | rc = select(0, &rfds, &wfds, &efds, &tv); | ||
291 | if (!handle_signaled && rc == SOCKET_ERROR) | ||
292 | return wsa_select_errno(WSAGetLastError()); | ||
293 | |||
294 | if (handle_signaled || (num_sockets && rc > 0)) | ||
295 | break; | ||
296 | |||
297 | timespent_ms += looptime_ms; | ||
298 | |||
299 | } while (timespent_ms < timeout_ms); | ||
300 | |||
301 | rc = 0; | ||
302 | num_handles = 0; | ||
303 | for (i = 0; i < nfds; i++) { | ||
304 | pfds[i].revents = 0; | ||
305 | |||
306 | if ((int)pfds[i].fd < 0) | ||
307 | continue; | ||
308 | |||
309 | if (is_socket(pfds[i].fd)) { | ||
310 | |||
311 | pfds[i].revents = compute_select_revents(pfds[i].fd, | ||
312 | pfds[i].events, &rfds, &wfds, &efds); | ||
313 | |||
314 | } else { | ||
315 | pfds[i].revents = compute_wait_revents( | ||
316 | handles[num_handles], pfds[i].events, num_handles, | ||
317 | wait_rc); | ||
318 | num_handles++; | ||
319 | } | ||
320 | |||
321 | if (pfds[i].revents) | ||
322 | rc++; | ||
323 | } | ||
324 | |||
325 | return rc; | ||
326 | } | ||
327 | |||