1 /* $NetBSD: tls_bio_ops.c,v 1.1.1.2 2010/06/17 18:07:08 tron Exp $ */ 2 3 /*++ 4 /* NAME 5 /* tls_bio_ops 3 6 /* SUMMARY 7 /* TLS network BIO 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 layer synchronizes the TLS network buffers with the network 42 /* while performing TLS handshake or input/output operations. 43 /* 44 /* When the TLS layer is active, it converts plain-text 45 /* data from Postfix into encrypted network data and vice versa. 46 /* However, to handle network timeout conditions, Postfix 47 /* needs to maintain control over network input/output. This 48 /* rules out the usual approach of placing the TLS layer 49 /* between the application and the network socket. 50 /* 51 /* As shown below, Postfix reads/writes plain-text data from/to 52 /* the TLS layer. The TLS layer informs Postfix when it needs 53 /* to read/write encrypted data from/to the network; Postfix 54 /* then reads/writes encrypted data from/to the TLS layer and 55 /* takes care of the network socket I/O. 56 /* 57 /* The TLS layer to network interface is realized with a BIO pair: 58 /* 59 /* Postfix SMTP layer | TLS layer 60 /* | 61 /* smtp/smtpd | 62 /* /\ || | 63 /* || \/ | 64 /* vstream read/write <===> TLS read/write/etc 65 /* | /\ || 66 /* | || \/ 67 /* | BIO pair (internal_bio) 68 /* | BIO pair (network_bio) 69 /* Postfix socket layer | /\ || 70 /* | || \/ 71 /* socket read/write <===> BIO read/write 72 /* /\ || | 73 /* || \/ | 74 /* network | 75 /* 76 /* The Postfix VSTREAM read/write operations invoke the SSL 77 /* read/write operations to send and retrieve plain-text data. Inside 78 /* the TLS layer the data are converted to/from TLS protocol. 79 /* 80 /* Whenever an SSL operation reports success, or whenever it 81 /* indicates that network input/output needs to happen, Postfix 82 /* uses the BIO read/write routines to synchronize the 83 /* network_bio buffer with the network. Writing data to the 84 /* network has precedence over reading from the network. This 85 /* is necessary to avoid deadlock. 86 /* 87 /* The BIO pair buffer size is set to 8192 bytes. This is much 88 /* larger than the typical Path MTU, and avoids sending tiny TCP 89 /* segments. It is also larger than the default VSTREAM_BUFSIZE 90 /* (4096, see vstream.h), so that large write operations can 91 /* be handled within one request. The internal buffer in the 92 /* network/network_bio handling layer is set to the same 93 /* value, since this seems to be reasonable. The code is 94 /* however able to handle arbitrary values smaller or larger 95 /* than the buffer size in the BIO pair. 96 /* 97 /* tls_bio_connect() performs the SSL_connect() operation while 98 /* synchronizing the network_bio buffer with the network. 99 /* 100 /* tls_bio_accept() performs the SSL_accept() operation while 101 /* synchronizing the network_bio buffer with the network. 102 /* 103 /* tls_bio_shutdown() performs the SSL_shutdown() operation while 104 /* synchronizing the network_bio buffer with the network. 105 /* 106 /* tls_bio_read() performs the SSL_read() operation while 107 /* synchronizing the network_bio buffer with the network. 108 /* 109 /* tls_bio_write() performs the SSL_write() operation while 110 /* synchronizing the network_bio buffer with the network. 111 /* 112 /* Arguments: 113 /* .IP fd 114 /* Network socket. 115 /* .IP buf 116 /* Read/write buffer. 117 /* .IP len 118 /* Read/write request size. 119 /* .IP timeout 120 /* Read/write timeout. 121 /* .IP TLScontext 122 /* TLS session state. 123 /* DIAGNOSTICS 124 /* The result value is -1 in case of a network read/write 125 /* error, otherwise it is the result value of the TLS operation. 126 /* LICENSE 127 /* .ad 128 /* .fi 129 /* This software is free. You can do with it whatever you want. 130 /* The original author kindly requests that you acknowledge 131 /* the use of his software. 132 /* AUTHOR(S) 133 /* Originally written by: 134 /* Lutz Jaenicke 135 /* BTU Cottbus 136 /* Allgemeine Elektrotechnik 137 /* Universitaetsplatz 3-4 138 /* D-03044 Cottbus, Germany 139 /* 140 /* Updated by: 141 /* Wietse Venema 142 /* IBM T.J. Watson Research 143 /* P.O. Box 704 144 /* Yorktown Heights, NY 10598, USA 145 /* 146 /* Victor Duchovni 147 /* Morgan Stanley 148 /*--*/ 149 150 /* System library. */ 151 152 #include <sys_defs.h> 153 154 #ifdef USE_TLS 155 156 /* Utility library. */ 157 158 #include <msg.h> 159 #include <iostuff.h> 160 161 /* TLS library. */ 162 163 #define TLS_INTERNAL 164 #include <tls.h> 165 166 /* Application-specific. */ 167 168 #define NETLAYER_BUFFERSIZE 8192 169 170 /* network_biopair_interop - synchronize network with BIO pair */ 171 172 static int network_biopair_interop(int fd, int timeout, BIO *network_bio) 173 { 174 const char *myname = "network_biopair_interop"; 175 int want_write; 176 int num_write; 177 int write_pos; 178 int from_bio; 179 int want_read; 180 int num_read; 181 int to_bio; 182 char buffer[NETLAYER_BUFFERSIZE]; 183 184 /* 185 * To avoid deadlock, write all pending data to the network before 186 * attempting to read from the network. 187 */ 188 while ((want_write = BIO_ctrl_pending(network_bio)) > 0) { 189 if (want_write > sizeof(buffer)) 190 want_write = sizeof(buffer); 191 from_bio = BIO_read(network_bio, buffer, want_write); 192 193 /* 194 * Write the complete buffer contents to the network. 195 */ 196 for (write_pos = 0; write_pos < from_bio; /* see below */ ) { 197 if (timeout > 0 && write_wait(fd, timeout) < 0) 198 return (-1); 199 num_write = write(fd, buffer + write_pos, from_bio - write_pos); 200 if (num_write <= 0) { 201 if ((num_write < 0) && (timeout > 0) && (errno == EAGAIN)) { 202 msg_warn("write() returns EAGAIN on a writable file descriptor!"); 203 msg_warn("pausing to avoid going into a tight select/write loop!"); 204 sleep(1); 205 } else { 206 msg_warn("%s: error writing %d bytes to the network: %m", 207 myname, from_bio - write_pos); 208 return (-1); 209 } 210 } else { 211 write_pos += num_write; 212 } 213 } 214 } 215 216 /* 217 * Read data from the network into the BIO pair. 218 */ 219 while ((want_read = BIO_ctrl_get_read_request(network_bio)) > 0) { 220 if (want_read > sizeof(buffer)) 221 want_read = sizeof(buffer); 222 if (timeout > 0 && read_wait(fd, timeout) < 0) 223 return (-1); 224 num_read = read(fd, buffer, want_read); 225 if (num_read == 0) 226 /* FIX 200412 Cannot return a zero read count. */ 227 return (-1); 228 if (num_read < 0) { 229 if ((num_read < 0) && (timeout > 0) && (errno == EAGAIN)) { 230 msg_warn("read() returns EAGAIN on a readable file descriptor!"); 231 msg_warn("pausing to avoid going into a tight select/write loop!"); 232 sleep(1); 233 } else { 234 msg_warn("%s: error reading %d bytes from the network: %m", 235 myname, want_read); 236 return (-1); 237 } 238 } else { 239 to_bio = BIO_write(network_bio, buffer, num_read); 240 if (to_bio != num_read) 241 msg_panic("%s: BIO_write error: to_bio != num_read", myname); 242 } 243 } 244 return (0); 245 } 246 247 /* tls_bio - perform SSL input/output operation with extreme prejudice */ 248 249 int tls_bio(int fd, int timeout, TLS_SESS_STATE *TLScontext, 250 int (*hsfunc) (SSL *), 251 int (*rfunc) (SSL *, void *, int), 252 int (*wfunc) (SSL *, const void *, int), 253 void *buf, int num) 254 { 255 const char *myname = "tls_bio"; 256 int status; 257 int err; 258 int retval = 0; 259 int biop_retval; 260 int done; 261 262 /* 263 * If necessary, retry the SSL handshake or read/write operation after 264 * handling any pending network I/O. 265 */ 266 for (done = 0; done == 0; /* void */ ) { 267 if (hsfunc) 268 status = hsfunc(TLScontext->con); 269 else if (rfunc) 270 status = rfunc(TLScontext->con, buf, num); 271 else if (wfunc) 272 status = wfunc(TLScontext->con, buf, num); 273 else 274 msg_panic("%s: nothing to do here", myname); 275 err = SSL_get_error(TLScontext->con, status); 276 277 #if (OPENSSL_VERSION_NUMBER <= 0x0090581fL) 278 279 /* 280 * There is a bug up to and including OpenSSL-0.9.5a: if an error 281 * occurs while checking the peers certificate due to some 282 * certificate error (e.g. as happend with a RSA-padding error), the 283 * error is put onto the error stack. If verification is not 284 * enforced, this error should be ignored, but the error-queue is not 285 * cleared, so we can find this error here. The bug has been fixed on 286 * May 28, 2000. 287 * 288 * This bug so far has only manifested as 4800:error:0407006A:rsa 289 * routines:RSA_padding_check_PKCS1_type_1:block type is not 290 * 01:rsa_pk1.c:100: 4800:error:04067072:rsa 291 * routines:RSA_EAY_PUBLIC_DECRYPT:padding check 292 * failed:rsa_eay.c:396: 4800:error:0D079006:asn1 encoding 293 * routines:ASN1_verify:bad get asn1 object call:a_verify.c:109: so 294 * that we specifically test for this error. We print the errors to 295 * the logfile and automatically clear the error queue. Then we retry 296 * to get another error code. We cannot do better, since we can only 297 * retrieve the last entry of the error-queue without actually 298 * cleaning it on the way. 299 * 300 * This workaround is secure, as verify_result is set to "failed" 301 * anyway. 302 */ 303 if (err == SSL_ERROR_SSL) { 304 if (ERR_peek_error() == 0x0407006AL) { 305 tls_print_errors(); 306 msg_info("OpenSSL <= 0.9.5a workaround called: certificate errors ignored"); 307 err = SSL_get_error(TLScontext->con, status); 308 } 309 } 310 #endif 311 312 /* 313 * Find out if we must retry the operation and/or if there is pending 314 * network I/O. 315 * 316 * XXX If we're the first to invoke SSL_shutdown(), then the operation 317 * isn't really complete when the call returns. We could hide that 318 * anomaly here and repeat the call. 319 */ 320 switch (err) { 321 case SSL_ERROR_NONE: /* success */ 322 retval = status; 323 done = 1; 324 /* FALLTHROUGH */ 325 case SSL_ERROR_WANT_WRITE: /* flush/update buffers */ 326 case SSL_ERROR_WANT_READ: 327 biop_retval = 328 network_biopair_interop(fd, timeout, TLScontext->network_bio); 329 if (biop_retval < 0) 330 return (-1); /* network read/write error */ 331 break; 332 333 /* 334 * With tls_timed_read() and tls_timed_write() the caller is the 335 * VSTREAM library module which is unaware of TLS, so we log the 336 * TLS error stack here. In a better world, each VSTREAM I/O 337 * object would provide an error reporting method in addition to 338 * the timed_read and timed_write methods, so that we would not 339 * need to have ad-hoc code like this. 340 */ 341 case SSL_ERROR_SSL: 342 if (rfunc || wfunc) 343 tls_print_errors(); 344 /* FALLTHROUGH */ 345 default: 346 retval = status; 347 done = 1; 348 break; 349 } 350 } 351 return (retval); 352 } 353 354 #endif 355