1/*	$NetBSD$	*/
2
3/*++
4/* NAME
5/*	tls_bio_ops 3
6/* SUMMARY
7/*	TLS network basic I/O management
8/* SYNOPSIS
9/*	#define TLS_INTERNAL
10/*	#include <tls.h>
11/*
12/*	int tls_bio_connect(fd, timeout, context)
13/*	int	fd;
14/*	int	timeout;
15/*	TLS_SESS_STATE *context;
16/*
17/*	int tls_bio_accept(fd, timeout, context)
18/*	int	fd;
19/*	int	timeout;
20/*	TLS_SESS_STATE *context;
21/*
22/*	int tls_bio_shutdown(fd, timeout, context)
23/*	int	fd;
24/*	int	timeout;
25/*	TLS_SESS_STATE *context;
26/*
27/*	int tls_bio_read(fd, buf, len, timeout, context)
28/*	int	fd;
29/*	void	*buf;
30/*	int	len;
31/*	int	timeout;
32/*	TLS_SESS_STATE *context;
33/*
34/*	int tls_bio_write(fd, buf, len, timeout, context)
35/*	int	fd;
36/*	void	*buf;
37/*	int	len;
38/*	int	timeout;
39/*	TLS_SESS_STATE *context;
40/* DESCRIPTION
41/*	This module enforces timeouts on non-blocking I/O while
42/*	performing TLS handshake or input/output operations.
43/*
44/*	The Postfix VSTREAM read/write routines invoke the
45/*	tls_bio_read/write routines to send and receive plain-text
46/*	data.  In addition, this module provides tls_bio_connect/accept
47/*	routines that trigger the initial TLS handshake.  The
48/*	tls_bio_xxx routines invoke the corresponding SSL routines
49/*	that translate the requests into TLS protocol messages.
50/*
51/*	Whenever an SSL operation indicates that network input (or
52/*	output) needs to happen, the tls_bio_xxx routines wait for
53/*	the network to become readable (or writable) within the
54/*	timeout limit, then retry the SSL operation. This works
55/*	because the network socket is in non-blocking mode.
56/*
57/*	tls_bio_connect() performs the SSL_connect() operation.
58/*
59/*	tls_bio_accept() performs the SSL_accept() operation.
60/*
61/*	tls_bio_shutdown() performs the SSL_shutdown() operation.
62/*
63/*	tls_bio_read() performs the SSL_read() operation.
64/*
65/*	tls_bio_write() performs the SSL_write() operation.
66/*
67/*	Arguments:
68/* .IP fd
69/*	Network socket.
70/* .IP buf
71/*	Read/write buffer.
72/* .IP len
73/*	Read/write request size.
74/* .IP timeout
75/*	Read/write timeout.
76/* .IP TLScontext
77/*	TLS session state.
78/* DIAGNOSTICS
79/*	The result value is -1 in case of a network read/write
80/*	error, otherwise it is the result value of the TLS operation.
81/* LICENSE
82/* .ad
83/* .fi
84/*	This software is free. You can do with it whatever you want.
85/*	The original author kindly requests that you acknowledge
86/*	the use of his software.
87/* AUTHOR(S)
88/*	Originally written by:
89/*	Lutz Jaenicke
90/*	BTU Cottbus
91/*	Allgemeine Elektrotechnik
92/*	Universitaetsplatz 3-4
93/*	D-03044 Cottbus, Germany
94/*
95/*	Updated by:
96/*	Wietse Venema
97/*	IBM T.J. Watson Research
98/*	P.O. Box 704
99/*	Yorktown Heights, NY 10598, USA
100/*
101/*	Victor Duchovni
102/*	Morgan Stanley
103/*--*/
104
105/* System library. */
106
107#include <sys_defs.h>
108
109#ifdef USE_TLS
110
111/* Utility library. */
112
113#include <msg.h>
114#include <iostuff.h>
115
116/* TLS library. */
117
118#define TLS_INTERNAL
119#include <tls.h>
120
121/* tls_bio - perform SSL input/output operation with extreme prejudice */
122
123int     tls_bio(int fd, int timeout, TLS_SESS_STATE *TLScontext,
124		        int (*hsfunc) (SSL *),
125		        int (*rfunc) (SSL *, void *, int),
126		        int (*wfunc) (SSL *, const void *, int),
127		        void *buf, int num)
128{
129    const char *myname = "tls_bio";
130    int     status;
131    int     err;
132    int     retval = 0;
133    int     done;
134
135    /*
136     * If necessary, retry the SSL handshake or read/write operation after
137     * handling any pending network I/O.
138     */
139    for (done = 0; done == 0; /* void */ ) {
140	if (hsfunc)
141	    status = hsfunc(TLScontext->con);
142	else if (rfunc)
143	    status = rfunc(TLScontext->con, buf, num);
144	else if (wfunc)
145	    status = wfunc(TLScontext->con, buf, num);
146	else
147	    msg_panic("%s: nothing to do here", myname);
148	err = SSL_get_error(TLScontext->con, status);
149
150#if (OPENSSL_VERSION_NUMBER <= 0x0090581fL)
151
152	/*
153	 * There is a bug up to and including OpenSSL-0.9.5a: if an error
154	 * occurs while checking the peers certificate due to some
155	 * certificate error (e.g. as happend with a RSA-padding error), the
156	 * error is put onto the error stack. If verification is not
157	 * enforced, this error should be ignored, but the error-queue is not
158	 * cleared, so we can find this error here. The bug has been fixed on
159	 * May 28, 2000.
160	 *
161	 * This bug so far has only manifested as 4800:error:0407006A:rsa
162	 * routines:RSA_padding_check_PKCS1_type_1:block type is not
163	 * 01:rsa_pk1.c:100: 4800:error:04067072:rsa
164	 * routines:RSA_EAY_PUBLIC_DECRYPT:padding check
165	 * failed:rsa_eay.c:396: 4800:error:0D079006:asn1 encoding
166	 * routines:ASN1_verify:bad get asn1 object call:a_verify.c:109: so
167	 * that we specifically test for this error. We print the errors to
168	 * the logfile and automatically clear the error queue. Then we retry
169	 * to get another error code. We cannot do better, since we can only
170	 * retrieve the last entry of the error-queue without actually
171	 * cleaning it on the way.
172	 *
173	 * This workaround is secure, as verify_result is set to "failed"
174	 * anyway.
175	 */
176	if (err == SSL_ERROR_SSL) {
177	    if (ERR_peek_error() == 0x0407006AL) {
178		tls_print_errors();
179		msg_info("OpenSSL <= 0.9.5a workaround called: certificate errors ignored");
180		err = SSL_get_error(TLScontext->con, status);
181	    }
182	}
183#endif
184
185	/*
186	 * Find out if we must retry the operation and/or if there is pending
187	 * network I/O.
188	 *
189	 * XXX If we're the first to invoke SSL_shutdown(), then the operation
190	 * isn't really complete when the call returns. We could hide that
191	 * anomaly here and repeat the call.
192	 */
193	switch (err) {
194	case SSL_ERROR_NONE:			/* success */
195	    retval = status;
196	    done = 1;
197	    break;
198	case SSL_ERROR_WANT_WRITE:
199	    if (write_wait(fd, timeout) < 0)
200		return (-1);			/* timeout error */
201	    break;
202	case SSL_ERROR_WANT_READ:
203	    if (read_wait(fd, timeout) < 0)
204		return (-1);			/* timeout error */
205	    break;
206
207	    /*
208	     * With tls_timed_read() and tls_timed_write() the caller is the
209	     * VSTREAM library module which is unaware of TLS, so we log the
210	     * TLS error stack here. In a better world, each VSTREAM I/O
211	     * object would provide an error reporting method in addition to
212	     * the timed_read and timed_write methods, so that we would not
213	     * need to have ad-hoc code like this.
214	     */
215	case SSL_ERROR_SSL:
216	    if (rfunc || wfunc)
217		tls_print_errors();
218	    /* FALLTHROUGH */
219	default:
220	    retval = status;
221	    done = 1;
222	    break;
223	}
224    }
225    return (retval);
226}
227
228#endif
229