aboutsummaryrefslogtreecommitdiff
path: root/apps/openssl
diff options
context:
space:
mode:
authorBrent Cook <bcook@openbsd.org>2015-09-12 07:48:06 -0500
committerBrent Cook <bcook@openbsd.org>2015-09-12 08:08:24 -0500
commit854f4f69af9003c0c29d3838001f549beaf36936 (patch)
tree913e183b140e6a974efa7643ec217d0f6d574257 /apps/openssl
parent34bfb6ecb5d178ee62b402ee344d0f6caf5cdad0 (diff)
downloadportable-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.am116
-rw-r--r--apps/openssl/compat/apps_win.c29
-rw-r--r--apps/openssl/compat/certhash_win.c13
-rw-r--r--apps/openssl/compat/poll_win.c327
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 @@
1include $(top_srcdir)/Makefile.am.common
2
3bin_PROGRAMS = openssl
4
5openssl_LDADD = $(PLATFORM_LDADD) $(PROG_LDADD)
6openssl_LDADD += $(top_builddir)/ssl/libssl.la
7openssl_LDADD += $(top_builddir)/crypto/libcrypto.la
8
9openssl_SOURCES = apps.c
10openssl_SOURCES += asn1pars.c
11openssl_SOURCES += ca.c
12openssl_SOURCES += ciphers.c
13openssl_SOURCES += cms.c
14openssl_SOURCES += crl.c
15openssl_SOURCES += crl2p7.c
16openssl_SOURCES += dgst.c
17openssl_SOURCES += dh.c
18openssl_SOURCES += dhparam.c
19openssl_SOURCES += dsa.c
20openssl_SOURCES += dsaparam.c
21openssl_SOURCES += ec.c
22openssl_SOURCES += ecparam.c
23openssl_SOURCES += enc.c
24openssl_SOURCES += errstr.c
25openssl_SOURCES += gendh.c
26openssl_SOURCES += gendsa.c
27openssl_SOURCES += genpkey.c
28openssl_SOURCES += genrsa.c
29openssl_SOURCES += nseq.c
30openssl_SOURCES += ocsp.c
31openssl_SOURCES += openssl.c
32openssl_SOURCES += passwd.c
33openssl_SOURCES += pkcs12.c
34openssl_SOURCES += pkcs7.c
35openssl_SOURCES += pkcs8.c
36openssl_SOURCES += pkey.c
37openssl_SOURCES += pkeyparam.c
38openssl_SOURCES += pkeyutl.c
39openssl_SOURCES += prime.c
40openssl_SOURCES += rand.c
41openssl_SOURCES += req.c
42openssl_SOURCES += rsa.c
43openssl_SOURCES += rsautl.c
44openssl_SOURCES += s_cb.c
45openssl_SOURCES += s_client.c
46openssl_SOURCES += s_server.c
47openssl_SOURCES += s_socket.c
48openssl_SOURCES += s_time.c
49openssl_SOURCES += sess_id.c
50openssl_SOURCES += smime.c
51openssl_SOURCES += speed.c
52openssl_SOURCES += spkac.c
53openssl_SOURCES += ts.c
54openssl_SOURCES += verify.c
55openssl_SOURCES += version.c
56openssl_SOURCES += x509.c
57
58if BUILD_CERTHASH
59openssl_SOURCES += certhash.c
60else
61openssl_SOURCES += compat/certhash_win.c
62endif
63
64if HOST_WIN
65openssl_SOURCES += compat/apps_win.c
66else
67openssl_SOURCES += apps_posix.c
68endif
69
70if !HAVE_POLL
71if HOST_WIN
72openssl_SOURCES += compat/poll_win.c
73endif
74endif
75
76if !HAVE_STRTONUM
77openssl_SOURCES += compat/strtonum.c
78endif
79
80noinst_HEADERS = apps.h
81noinst_HEADERS += progs.h
82noinst_HEADERS += s_apps.h
83noinst_HEADERS += testdsa.h
84noinst_HEADERS += testrsa.h
85noinst_HEADERS += timeouts.h
86
87EXTRA_DIST = cert.pem
88EXTRA_DIST += openssl.cnf
89EXTRA_DIST += x509v3.cnf
90
91install-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
106uninstall-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
12double
13app_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
8int
9certhash_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
20static int
21conn_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
37static int
38conn_has_oob_data(int fd)
39{
40 char buf[1];
41 return (recv(fd, buf, 1, MSG_PEEK | MSG_OOB) == 1);
42}
43
44static int
45is_socket(int fd)
46{
47 if (fd < 3)
48 return 0;
49 WSANETWORKEVENTS events;
50 return (WSAEnumNetworkEvents((SOCKET)fd, NULL, &events) == 0);
51}
52
53static int
54compute_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
81static int
82compute_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
130static int
131wsa_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
159int
160poll(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