1 /* $NetBSD: tls_bio_ops.c,v 1.1.1.4 2013/01/02 18:59:04 tron Exp $ */ 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 VSTREAM-style timeouts on non-blocking 42 /* I/O while 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 /* A result value > 0 means successful completion. 80 /* 81 /* A result value < 0 means that the requested operation did 82 /* not complete due to TLS protocol failure, system call 83 /* failure, or for any reason described under "in addition" 84 /* below. 85 /* 86 /* A result value of 0 from tls_bio_shutdown() means that the 87 /* operation is in progress. A result value of 0 from other 88 /* tls_bio_ops(3) operations means that the remote party either 89 /* closed the network connection or that it sent a TLS shutdown 90 /* request. 91 /* 92 /* Upon return from the tls_bio_ops(3) routines the global 93 /* errno value is non-zero when the requested operation did not 94 /* complete due to system call failure. 95 /* 96 /* In addition, the result value is set to -1, and the global 97 /* errno value is set to ETIMEDOUT, when some network read/write 98 /* operation did not complete within the time limit. 99 /* LICENSE 100 /* .ad 101 /* .fi 102 /* This software is free. You can do with it whatever you want. 103 /* The original author kindly requests that you acknowledge 104 /* the use of his software. 105 /* AUTHOR(S) 106 /* Originally written by: 107 /* Lutz Jaenicke 108 /* BTU Cottbus 109 /* Allgemeine Elektrotechnik 110 /* Universitaetsplatz 3-4 111 /* D-03044 Cottbus, Germany 112 /* 113 /* Updated by: 114 /* Wietse Venema 115 /* IBM T.J. Watson Research 116 /* P.O. Box 704 117 /* Yorktown Heights, NY 10598, USA 118 /* 119 /* Victor Duchovni 120 /* Morgan Stanley 121 /*--*/ 122 123 /* System library. */ 124 125 #include <sys_defs.h> 126 #include <sys/time.h> 127 128 #ifndef timersub 129 /* res = a - b */ 130 #define timersub(a, b, res) do { \ 131 (res)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ 132 (res)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ 133 if ((res)->tv_usec < 0) { \ 134 (res)->tv_sec--; \ 135 (res)->tv_usec += 1000000; \ 136 } \ 137 } while (0) 138 #endif 139 140 #ifdef USE_TLS 141 142 /* Utility library. */ 143 144 #include <msg.h> 145 #include <iostuff.h> 146 147 /* TLS library. */ 148 149 #define TLS_INTERNAL 150 #include <tls.h> 151 152 /* tls_bio - perform SSL input/output operation with extreme prejudice */ 153 154 int tls_bio(int fd, int timeout, TLS_SESS_STATE *TLScontext, 155 int (*hsfunc) (SSL *), 156 int (*rfunc) (SSL *, void *, int), 157 int (*wfunc) (SSL *, const void *, int), 158 void *buf, int num) 159 { 160 const char *myname = "tls_bio"; 161 int status; 162 int err; 163 int enable_deadline; 164 struct timeval time_left; /* amount of time left */ 165 struct timeval time_deadline; /* time of deadline */ 166 struct timeval time_now; /* time after SSL_mumble() call */ 167 168 /* 169 * Compensation for interface mis-match: With VSTREAMs, timeout <= 0 170 * means wait forever; with the read/write_wait() calls below, we need to 171 * specify timeout < 0 instead. 172 * 173 * Safety: no time limit means no deadline. 174 */ 175 if (timeout <= 0) { 176 timeout = -1; 177 enable_deadline = 0; 178 } 179 180 /* 181 * Deadline management is simpler than with VSTREAMs, because we don't 182 * need to decrement a per-stream time limit. We just work within the 183 * budget that is available for this tls_bio() call. 184 */ 185 else { 186 enable_deadline = 187 vstream_fstat(TLScontext->stream, VSTREAM_FLAG_DEADLINE); 188 if (enable_deadline) { 189 GETTIMEOFDAY(&time_deadline); 190 time_deadline.tv_sec += timeout; 191 } 192 } 193 194 /* 195 * If necessary, retry the SSL handshake or read/write operation after 196 * handling any pending network I/O. 197 */ 198 for (;;) { 199 if (hsfunc) 200 status = hsfunc(TLScontext->con); 201 else if (rfunc) 202 status = rfunc(TLScontext->con, buf, num); 203 else if (wfunc) 204 status = wfunc(TLScontext->con, buf, num); 205 else 206 msg_panic("%s: nothing to do here", myname); 207 err = SSL_get_error(TLScontext->con, status); 208 209 #if (OPENSSL_VERSION_NUMBER <= 0x0090581fL) 210 211 /* 212 * There is a bug up to and including OpenSSL-0.9.5a: if an error 213 * occurs while checking the peers certificate due to some 214 * certificate error (e.g. as happend with a RSA-padding error), the 215 * error is put onto the error stack. If verification is not 216 * enforced, this error should be ignored, but the error-queue is not 217 * cleared, so we can find this error here. The bug has been fixed on 218 * May 28, 2000. 219 * 220 * This bug so far has only manifested as 4800:error:0407006A:rsa 221 * routines:RSA_padding_check_PKCS1_type_1:block type is not 222 * 01:rsa_pk1.c:100: 4800:error:04067072:rsa 223 * routines:RSA_EAY_PUBLIC_DECRYPT:padding check 224 * failed:rsa_eay.c:396: 4800:error:0D079006:asn1 encoding 225 * routines:ASN1_verify:bad get asn1 object call:a_verify.c:109: so 226 * that we specifically test for this error. We print the errors to 227 * the logfile and automatically clear the error queue. Then we retry 228 * to get another error code. We cannot do better, since we can only 229 * retrieve the last entry of the error-queue without actually 230 * cleaning it on the way. 231 * 232 * This workaround is secure, as verify_result is set to "failed" 233 * anyway. 234 */ 235 if (err == SSL_ERROR_SSL) { 236 if (ERR_peek_error() == 0x0407006AL) { 237 tls_print_errors(); 238 msg_info("OpenSSL <= 0.9.5a workaround called: certificate errors ignored"); 239 err = SSL_get_error(TLScontext->con, status); 240 } 241 } 242 #endif 243 244 /* 245 * Correspondence between SSL_ERROR_* error codes and tls_bio_(read, 246 * write, accept, connect, shutdown) return values (for brevity: 247 * retval). 248 * 249 * SSL_ERROR_NONE corresponds with retval > 0. With SSL_(read, write) 250 * this is the number of plaintext bytes sent or received. With 251 * SSL_(accept, connect, shutdown) this means that the operation was 252 * completed successfully. 253 * 254 * SSL_ERROR_WANT_(WRITE, READ) start a new loop iteration, or force 255 * (retval = -1, errno = ETIMEDOUT) when the time limit is exceeded. 256 * 257 * All other SSL_ERROR_* cases correspond with retval <= 0. With 258 * SSL_(read, write, accept, connect) retval == 0 means that the 259 * remote party either closed the network connection or that it 260 * requested TLS shutdown; with SSL_shutdown() retval == 0 means that 261 * our own shutdown request is in progress. With all operations 262 * retval < 0 means that there was an error. In the latter case, 263 * SSL_ERROR_SYSCALL means that error details are returned via the 264 * errno value. 265 * 266 * Find out if we must retry the operation and/or if there is pending 267 * network I/O. 268 * 269 * XXX If we're the first to invoke SSL_shutdown(), then the operation 270 * isn't really complete when the call returns. We could hide that 271 * anomaly here and repeat the call. 272 */ 273 switch (err) { 274 case SSL_ERROR_WANT_WRITE: 275 case SSL_ERROR_WANT_READ: 276 if (enable_deadline) { 277 GETTIMEOFDAY(&time_now); 278 timersub(&time_deadline, &time_now, &time_left); 279 timeout = time_left.tv_sec + (time_left.tv_usec > 0); 280 if (timeout <= 0) { 281 errno = ETIMEDOUT; 282 return (-1); 283 } 284 } 285 if (err == SSL_ERROR_WANT_WRITE) { 286 if (write_wait(fd, timeout) < 0) 287 return (-1); /* timeout error */ 288 } else { 289 if (read_wait(fd, timeout) < 0) 290 return (-1); /* timeout error */ 291 } 292 break; 293 294 /* 295 * Unhandled cases: SSL_ERROR_WANT_(ACCEPT, CONNECT, X509_LOOKUP) 296 * etc. Historically, Postfix silently treated these as ordinary 297 * I/O errors so we don't really know how common they are. For 298 * now, we just log a warning. 299 */ 300 default: 301 msg_warn("%s: unexpected SSL_ERROR code %d", myname, err); 302 /* FALLTHROUGH */ 303 304 /* 305 * With tls_timed_read() and tls_timed_write() the caller is the 306 * VSTREAM library module which is unaware of TLS, so we log the 307 * TLS error stack here. In a better world, each VSTREAM I/O 308 * object would provide an error reporting method in addition to 309 * the timed_read and timed_write methods, so that we would not 310 * need to have ad-hoc code like this. 311 */ 312 case SSL_ERROR_SSL: 313 if (rfunc || wfunc) 314 tls_print_errors(); 315 /* FALLTHROUGH */ 316 case SSL_ERROR_ZERO_RETURN: 317 case SSL_ERROR_NONE: 318 errno = 0; /* avoid bogus warnings */ 319 /* FALLTHROUGH */ 320 case SSL_ERROR_SYSCALL: 321 return (status); 322 } 323 } 324 } 325 326 #endif 327