Standard preamble:
========================================================================
..
.... Set up some character translations and predefined strings. \*(-- will
give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
double quote, and \*(R" will give a right double quote. \*(C+ will
give a nicer C++. Capital omega is used to do unbreakable dashes and
therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
nothing in troff, for use with C<>.
.tr \(*W- . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\}
Escape single quotes in literal strings from groff's Unicode transform.
If the F register is >0, we'll generate index entries on stderr for
titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
entries marked with X<> in POD. Of course, you'll have to process the
output yourself in some meaningful fashion.
Avoid warning from groff about undefined register 'F'.
.. .nr rF 0 . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF
Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
Fear. Run. Save yourself. No user-serviceable parts.
. \" fudge factors for nroff and troff . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] .\} . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents . \" corrections for vroff . \" for low resolution devices (crt and lpr) \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} ========================================================================
Title "BIO_F_SSL 3"
way too many mistakes in technical documents.
I/O performed on an \s-1SSL BIO\s0 communicates using the \s-1SSL\s0 protocol with the SSLs read and write BIOs. If an \s-1SSL\s0 connection is not established then an attempt is made to establish one on the first I/O call.
If a \s-1BIO\s0 is appended to an \s-1SSL BIO\s0 using BIO_push() it is automatically used as the \s-1SSL\s0 BIOs read and write BIOs.
Calling BIO_reset() on an \s-1SSL BIO\s0 closes down any current \s-1SSL\s0 connection by calling SSL_shutdown(). BIO_reset() is then sent to the next \s-1BIO\s0 in the chain: this will typically disconnect the underlying transport. The \s-1SSL BIO\s0 is then reset to the initial accept or connect state.
If the close flag is set when an \s-1SSL BIO\s0 is freed then the internal \s-1SSL\s0 structure is also freed using SSL_free().
\fBBIO_set_ssl() sets the internal \s-1SSL\s0 pointer of \s-1SSL BIO\s0 b to ssl using the close flag c.
\fBBIO_get_ssl() retrieves the \s-1SSL\s0 pointer of \s-1SSL BIO\s0 b, it can then be manipulated using the standard \s-1SSL\s0 library functions.
\fBBIO_set_ssl_mode() sets the \s-1SSL BIO\s0 mode to client. If client is 1 client mode is set. If client is 0 server mode is set.
\fBBIO_set_ssl_renegotiate_bytes() sets the renegotiate byte count of \s-1SSL BIO\s0 b to num. When set after every num bytes of I/O (read and write) the \s-1SSL\s0 session is automatically renegotiated. num must be at least 512 bytes.
\fBBIO_set_ssl_renegotiate_timeout() sets the renegotiate timeout of \s-1SSL BIO\s0 b to seconds. When the renegotiate timeout elapses the session is automatically renegotiated.
\fBBIO_get_num_renegotiates() returns the total number of session renegotiations due to I/O or timeout of \s-1SSL BIO\s0 b.
\fBBIO_new_ssl() allocates an \s-1SSL BIO\s0 using \s-1SSL_CTX\s0 ctx and using client mode if client is non zero.
\fBBIO_new_ssl_connect() creates a new \s-1BIO\s0 chain consisting of an \s-1SSL BIO\s0 (using ctx) followed by a connect \s-1BIO.\s0
\fBBIO_new_buffer_ssl_connect() creates a new \s-1BIO\s0 chain consisting of a buffering \s-1BIO,\s0 an \s-1SSL BIO\s0 (using ctx), and a connect \s-1BIO.\s0
\fBBIO_ssl_copy_session_id() copies an \s-1SSL\s0 session id between \s-1BIO\s0 chains from and to. It does this by locating the \s-1SSL\s0 BIOs in each chain and calling SSL_copy_session_id() on the internal \s-1SSL\s0 pointer.
\fBBIO_ssl_shutdown() closes down an \s-1SSL\s0 connection on \s-1BIO\s0 chain bio. It does this by locating the \s-1SSL BIO\s0 in the chain and calling SSL_shutdown() on its internal \s-1SSL\s0 pointer.
\fBBIO_do_handshake() attempts to complete an \s-1SSL\s0 handshake on the supplied \s-1BIO\s0 and establish the \s-1SSL\s0 connection. For non-SSL BIOs the connection is done typically at \s-1TCP\s0 level. If domain name resolution yields multiple \s-1IP\s0 addresses all of them are tried after connect() failures. The function returns 1 if the connection was established successfully. A zero or negative value is returned if the connection could not be established. The call BIO_should_retry() should be used for nonblocking connect BIOs to determine if the call should be retried. If a connection has already been established this call has no effect.
The \s-1SSL\s0 flag \s-1SSL_AUTO_RETRY\s0 can be set to disable this behaviour. That is when this flag is set an \s-1SSL BIO\s0 using a blocking transport will never request a retry.
Since unknown BIO_ctrl() operations are sent through filter BIOs the servers name and port can be set using BIO_set_host() on the \s-1BIO\s0 returned by BIO_new_ssl_connect() without having to locate the connect \s-1BIO\s0 first.
Applications do not have to call BIO_do_handshake() but may wish to do so to separate the handshake process from other I/O processing.
\fBBIO_set_ssl(), BIO_get_ssl(), BIO_set_ssl_mode(), \fBBIO_set_ssl_renegotiate_bytes(), BIO_set_ssl_renegotiate_timeout(), \fBBIO_get_num_renegotiates(), and BIO_do_handshake() are implemented as macros.
\fBBIO_set_ssl(), BIO_get_ssl(), BIO_set_ssl_mode(), BIO_set_ssl_renegotiate_bytes(), \fBBIO_set_ssl_renegotiate_timeout() and BIO_get_num_renegotiates() return 1 on success or a value which is less than or equal to 0 if an error occurred.
\fBBIO_new_ssl(), BIO_new_ssl_connect() and BIO_new_buffer_ssl_connect() return a valid \s-1BIO\s0 structure on success or \s-1NULL\s0 if an error occurred.
\fBBIO_ssl_copy_session_id() returns 1 on success or 0 on error.
\fBBIO_do_handshake() returns 1 if the connection was established successfully. A zero or negative value is returned if the connection could not be established.
.Vb 5 BIO *sbio, *out; int len; char tmpbuf[1024]; SSL_CTX *ctx; SSL *ssl; \& /* XXX Seed the PRNG if needed. */ \& ctx = SSL_CTX_new(TLS_client_method()); \& /* XXX Set verify paths and mode here. */ \& sbio = BIO_new_ssl_connect(ctx); BIO_get_ssl(sbio, &ssl); if (ssl == NULL) { fprintf(stderr, "Can\*(Aqt locate SSL pointer\en"); ERR_print_errors_fp(stderr); exit(1); } \& /* XXX We might want to do other things with ssl here */ \& /* An empty host part means the loopback address */ BIO_set_conn_hostname(sbio, ":https"); \& out = BIO_new_fp(stdout, BIO_NOCLOSE); if (BIO_do_connect(sbio) <= 0) { fprintf(stderr, "Error connecting to server\en"); ERR_print_errors_fp(stderr); exit(1); } \& /* XXX Could examine ssl here to get connection info */ \& BIO_puts(sbio, "GET / HTTP/1.0\en\en"); for (;;) { len = BIO_read(sbio, tmpbuf, 1024); if (len <= 0) break; BIO_write(out, tmpbuf, len); } BIO_free_all(sbio); BIO_free(out); .Ve
Here is a simple server example. It makes use of a buffering \s-1BIO\s0 to allow lines to be read from the \s-1SSL BIO\s0 using BIO_gets. It creates a pseudo web page containing the actual request from a client and also echoes the request to standard output.
.Vb 5 BIO *sbio, *bbio, *acpt, *out; int len; char tmpbuf[1024]; SSL_CTX *ctx; SSL *ssl; \& /* XXX Seed the PRNG if needed. */ \& ctx = SSL_CTX_new(TLS_server_method()); if (!SSL_CTX_use_certificate_file(ctx, "server.pem", SSL_FILETYPE_PEM) || !SSL_CTX_use_PrivateKey_file(ctx, "server.pem", SSL_FILETYPE_PEM) || !SSL_CTX_check_private_key(ctx)) { fprintf(stderr, "Error setting up SSL_CTX\en"); ERR_print_errors_fp(stderr); exit(1); } \& /* XXX Other things like set verify locations, EDH temp callbacks. */ \& /* New SSL BIO setup as server */ sbio = BIO_new_ssl(ctx, 0); BIO_get_ssl(sbio, &ssl); if (ssl == NULL) { fprintf(stderr, "Can\*(Aqt locate SSL pointer\en"); ERR_print_errors_fp(stderr); exit(1); } \& bbio = BIO_new(BIO_f_buffer()); sbio = BIO_push(bbio, sbio); acpt = BIO_new_accept("4433"); \& /* * By doing this when a new connection is established * we automatically have sbio inserted into it. The * BIO chain is now \*(Aqswallowed\*(Aq by the accept BIO and * will be freed when the accept BIO is freed. */ BIO_set_accept_bios(acpt, sbio); out = BIO_new_fp(stdout, BIO_NOCLOSE); \& /* First call to BIO_do_accept() sets up accept BIO */ if (BIO_do_accept(acpt) <= 0) { fprintf(stderr, "Error setting up accept BIO\en"); ERR_print_errors_fp(stderr); exit(1); } .Ve
/* Second call to BIO_do_accept() waits for incoming connection */ if (BIO_do_accept(acpt) <= 0) { fprintf(stderr, \*(L"Error accepting connection\en\*(R"); ERR_print_errors_fp(stderr); exit\|(1); }
.Vb 3 /* We only want one connection so remove and free accept BIO */ sbio = BIO_pop(acpt); BIO_free_all(acpt); \& if (BIO_do_handshake(sbio) <= 0) { fprintf(stderr, "Error in SSL handshake\en"); ERR_print_errors_fp(stderr); exit(1); } \& BIO_puts(sbio, "HTTP/1.0 200 OK\er\enContent-type: text/plain\er\en\er\en"); BIO_puts(sbio, "\er\enConnection Established\er\enRequest headers:\er\en"); BIO_puts(sbio, "--------------------------------------------------\er\en"); \& for (;;) { len = BIO_gets(sbio, tmpbuf, 1024); if (len <= 0) break; BIO_write(sbio, tmpbuf, len); BIO_write(out, tmpbuf, len); /* Look for blank line signifying end of headers*/ if (tmpbuf[0] == \*(Aq\er\*(Aq || tmpbuf[0] == \*(Aq\en\*(Aq) break; } \& BIO_puts(sbio, "--------------------------------------------------\er\en"); BIO_puts(sbio, "\er\en"); BIO_flush(sbio); BIO_free_all(sbio); .Ve
Licensed under the Apache License 2.0 (the \*(L"License\*(R"). You may not use this file except in compliance with the License. You can obtain a copy in the file \s-1LICENSE\s0 in the source distribution or at <https://www.openssl.org/source/license.html>.