609 lines
14 KiB
Groff
609 lines
14 KiB
Groff
.\" $OpenBSD: BIO_f_ssl.3,v 1.16 2024/01/13 18:37:51 tb Exp $
|
|
.\" full merge up to: OpenSSL f672aee4 Feb 9 11:52:40 2016 -0500
|
|
.\" selective merge up to: OpenSSL 61f805c1 Jan 16 01:01:46 2018 +0800
|
|
.\"
|
|
.\" This file was written by Dr. Stephen Henson <steve@openssl.org>.
|
|
.\" Copyright (c) 2000, 2003, 2009, 2014-2016 The OpenSSL Project.
|
|
.\" All rights reserved.
|
|
.\"
|
|
.\" Redistribution and use in source and binary forms, with or without
|
|
.\" modification, are permitted provided that the following conditions
|
|
.\" are met:
|
|
.\"
|
|
.\" 1. Redistributions of source code must retain the above copyright
|
|
.\" notice, this list of conditions and the following disclaimer.
|
|
.\"
|
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
|
.\" notice, this list of conditions and the following disclaimer in
|
|
.\" the documentation and/or other materials provided with the
|
|
.\" distribution.
|
|
.\"
|
|
.\" 3. All advertising materials mentioning features or use of this
|
|
.\" software must display the following acknowledgment:
|
|
.\" "This product includes software developed by the OpenSSL Project
|
|
.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
|
.\"
|
|
.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
|
.\" endorse or promote products derived from this software without
|
|
.\" prior written permission. For written permission, please contact
|
|
.\" openssl-core@openssl.org.
|
|
.\"
|
|
.\" 5. Products derived from this software may not be called "OpenSSL"
|
|
.\" nor may "OpenSSL" appear in their names without prior written
|
|
.\" permission of the OpenSSL Project.
|
|
.\"
|
|
.\" 6. Redistributions of any form whatsoever must retain the following
|
|
.\" acknowledgment:
|
|
.\" "This product includes software developed by the OpenSSL Project
|
|
.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
|
.\"
|
|
.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
|
.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
|
.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
|
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
.\"
|
|
.Dd $Mdocdate: January 13 2024 $
|
|
.Dt BIO_F_SSL 3
|
|
.Os
|
|
.Sh NAME
|
|
.Nm BIO_f_ssl ,
|
|
.Nm BIO_set_ssl ,
|
|
.Nm BIO_get_ssl ,
|
|
.Nm BIO_set_ssl_mode ,
|
|
.Nm BIO_set_ssl_renegotiate_bytes ,
|
|
.Nm BIO_get_num_renegotiates ,
|
|
.Nm BIO_set_ssl_renegotiate_timeout ,
|
|
.Nm BIO_new_ssl ,
|
|
.Nm BIO_new_ssl_connect ,
|
|
.Nm BIO_new_buffer_ssl_connect ,
|
|
.Nm BIO_ssl_copy_session_id ,
|
|
.Nm BIO_ssl_shutdown ,
|
|
.Nm BIO_do_handshake
|
|
.Nd SSL BIO
|
|
.Sh SYNOPSIS
|
|
.In openssl/bio.h
|
|
.In openssl/ssl.h
|
|
.Ft const BIO_METHOD *
|
|
.Fn BIO_f_ssl void
|
|
.Ft long
|
|
.Fo BIO_set_ssl
|
|
.Fa "BIO *b"
|
|
.Fa "SSL *ssl"
|
|
.Fa "long c"
|
|
.Fc
|
|
.Ft long
|
|
.Fo BIO_get_ssl
|
|
.Fa "BIO *b"
|
|
.Fa "SSL *sslp"
|
|
.Fc
|
|
.Ft long
|
|
.Fo BIO_set_ssl_mode
|
|
.Fa "BIO *b"
|
|
.Fa "long client"
|
|
.Fc
|
|
.Ft long
|
|
.Fo BIO_set_ssl_renegotiate_bytes
|
|
.Fa "BIO *b"
|
|
.Fa "long num"
|
|
.Fc
|
|
.Ft long
|
|
.Fo BIO_set_ssl_renegotiate_timeout
|
|
.Fa "BIO *b"
|
|
.Fa "long seconds"
|
|
.Fc
|
|
.Ft long
|
|
.Fo BIO_get_num_renegotiates
|
|
.Fa "BIO *b"
|
|
.Fc
|
|
.Ft BIO *
|
|
.Fn BIO_new_ssl "SSL_CTX *ctx" "int client"
|
|
.Ft BIO *
|
|
.Fn BIO_new_ssl_connect "SSL_CTX *ctx"
|
|
.Ft BIO *
|
|
.Fn BIO_new_buffer_ssl_connect "SSL_CTX *ctx"
|
|
.Ft int
|
|
.Fn BIO_ssl_copy_session_id "BIO *to" "BIO *from"
|
|
.Ft void
|
|
.Fn BIO_ssl_shutdown "BIO *bio"
|
|
.Ft long
|
|
.Fn BIO_do_handshake "BIO *b"
|
|
.Sh DESCRIPTION
|
|
.Fn BIO_f_ssl
|
|
returns the
|
|
.Vt SSL
|
|
.Vt BIO
|
|
method.
|
|
This is a filter
|
|
.Vt BIO
|
|
which is a wrapper around the OpenSSL
|
|
.Vt SSL
|
|
routines adding a
|
|
.Vt BIO
|
|
.Dq flavor
|
|
to SSL I/O.
|
|
.Pp
|
|
I/O performed on an
|
|
.Vt SSL
|
|
.Vt BIO
|
|
communicates using the SSL protocol with
|
|
the
|
|
.Vt SSL Ns 's
|
|
read and write
|
|
.Vt BIO Ns s .
|
|
If an SSL connection is not established then an attempt is made to establish
|
|
one on the first I/O call.
|
|
.Pp
|
|
If a
|
|
.Vt BIO
|
|
is appended to an
|
|
.Vt SSL
|
|
.Vt BIO
|
|
using
|
|
.Xr BIO_push 3 ,
|
|
it is automatically used as the
|
|
.Vt SSL
|
|
.Vt BIO Ns 's read and write
|
|
.Vt BIO Ns s .
|
|
.Pp
|
|
Calling
|
|
.Xr BIO_reset 3
|
|
on an
|
|
.Vt SSL
|
|
.Vt BIO
|
|
closes down any current SSL connection by calling
|
|
.Xr SSL_shutdown 3 .
|
|
.Xr BIO_reset 3
|
|
is then sent to the next
|
|
.Vt BIO
|
|
in the chain; this will typically disconnect the underlying transport.
|
|
The
|
|
.Vt SSL
|
|
.Vt BIO
|
|
is then reset to the initial accept or connect state.
|
|
.Pp
|
|
If the close flag is set when an
|
|
.Vt SSL
|
|
.Vt BIO
|
|
is freed then the internal
|
|
.Vt SSL
|
|
structure is also freed using
|
|
.Xr SSL_free 3 .
|
|
.Pp
|
|
.Fn BIO_set_ssl
|
|
sets the internal
|
|
.Vt SSL
|
|
pointer of
|
|
.Vt BIO
|
|
.Fa b
|
|
to
|
|
.Fa ssl
|
|
using
|
|
the close flag
|
|
.Fa c .
|
|
.Pp
|
|
.Fn BIO_get_ssl
|
|
retrieves the
|
|
.Vt SSL
|
|
pointer of
|
|
.Vt BIO
|
|
.Fa b ;
|
|
it can then be manipulated using the standard SSL library functions.
|
|
.Pp
|
|
.Fn BIO_set_ssl_mode
|
|
sets the
|
|
.Vt SSL
|
|
.Vt BIO
|
|
mode to
|
|
.Fa client .
|
|
If
|
|
.Fa client
|
|
is 1, client mode is set.
|
|
If
|
|
.Fa client
|
|
is 0, server mode is set.
|
|
.Pp
|
|
.Fn BIO_set_ssl_renegotiate_bytes
|
|
sets the renegotiate byte count to
|
|
.Fa num .
|
|
When set, after every
|
|
.Fa num
|
|
bytes of I/O (read and write) the SSL session is automatically renegotiated.
|
|
.Fa num
|
|
must be at least 512 bytes.
|
|
.Pp
|
|
.Fn BIO_set_ssl_renegotiate_timeout
|
|
sets the renegotiate timeout to
|
|
.Fa seconds .
|
|
When the renegotiate timeout elapses, the session is automatically renegotiated.
|
|
.Pp
|
|
.Fn BIO_get_num_renegotiates
|
|
returns the total number of session renegotiations due to I/O or timeout.
|
|
.Pp
|
|
.Fn BIO_new_ssl
|
|
allocates an
|
|
.Vt SSL
|
|
.Vt BIO
|
|
using
|
|
.Vt SSL_CTX
|
|
.Va ctx
|
|
and using client mode if
|
|
.Fa client
|
|
is nonzero.
|
|
.Pp
|
|
.Fn BIO_new_ssl_connect
|
|
creates a new
|
|
.Vt BIO
|
|
chain consisting of an
|
|
.Vt SSL
|
|
.Vt BIO
|
|
(using
|
|
.Fa ctx )
|
|
followed by a connect BIO.
|
|
.Pp
|
|
.Fn BIO_new_buffer_ssl_connect
|
|
creates a new
|
|
.Vt BIO
|
|
chain consisting of a buffering
|
|
.Vt BIO ,
|
|
an
|
|
.Vt SSL
|
|
.Vt BIO
|
|
(using
|
|
.Fa ctx )
|
|
and a connect
|
|
.Vt BIO .
|
|
.Pp
|
|
.Fn BIO_ssl_copy_session_id
|
|
copies an SSL session id between
|
|
.Vt BIO
|
|
chains
|
|
.Fa from
|
|
and
|
|
.Fa to .
|
|
It does this by locating the
|
|
.Vt SSL
|
|
.Vt BIO Ns s
|
|
in each chain and calling
|
|
.Xr SSL_copy_session_id 3
|
|
on the internal
|
|
.Vt SSL
|
|
pointer.
|
|
.Pp
|
|
.Fn BIO_ssl_shutdown
|
|
closes down an SSL connection on
|
|
.Vt BIO
|
|
chain
|
|
.Fa bio .
|
|
It does this by locating the
|
|
.Vt SSL
|
|
.Vt BIO
|
|
in the
|
|
chain and calling
|
|
.Xr SSL_shutdown 3
|
|
on its internal
|
|
.Vt SSL
|
|
pointer.
|
|
.Pp
|
|
.Fn BIO_do_handshake
|
|
attempts to complete an SSL handshake on the supplied
|
|
.Vt BIO
|
|
and establish the SSL connection.
|
|
It returns 1 if the connection was established successfully.
|
|
A zero or negative value is returned if the connection could not be
|
|
established; the call
|
|
.Xr BIO_should_retry 3
|
|
should be used for non blocking connect
|
|
.Vt BIO Ns s
|
|
to determine if the call should be retried.
|
|
If an SSL connection has already been established, this call has no effect.
|
|
.Pp
|
|
When a chain containing an SSL BIO is copied with
|
|
.Xr BIO_dup_chain 3 ,
|
|
.Xr SSL_dup 3
|
|
is called internally to copy the
|
|
.Vt SSL
|
|
object from the existing BIO object to the new BIO object,
|
|
and the internal data related to
|
|
.Fn BIO_set_ssl_renegotiate_bytes
|
|
and
|
|
.Fn BIO_set_ssl_renegotiate_timeout
|
|
is also copied.
|
|
.Pp
|
|
.Vt SSL
|
|
.Vt BIO Ns s
|
|
are exceptional in that if the underlying transport is non-blocking they can
|
|
still request a retry in exceptional circumstances.
|
|
Specifically this will happen if a session renegotiation takes place during a
|
|
.Xr BIO_read 3
|
|
operation.
|
|
One case where this happens is when step up occurs.
|
|
.Pp
|
|
In OpenSSL 0.9.6 and later the SSL flag
|
|
.Dv SSL_AUTO_RETRY
|
|
can be set to disable this behaviour.
|
|
In other words, when this flag is set an
|
|
.Vt SSL
|
|
.Vt BIO
|
|
using a blocking transport will never request a retry.
|
|
.Pp
|
|
Since unknown
|
|
.Xr BIO_ctrl 3
|
|
operations are sent through filter
|
|
.Vt BIO Ns s ,
|
|
the server name and port can be set using
|
|
.Xr BIO_set_conn_hostname 3
|
|
and
|
|
.Xr BIO_set_conn_port 3
|
|
on the
|
|
.Vt BIO
|
|
returned by
|
|
.Fn BIO_new_ssl_connect
|
|
without having to locate the connect
|
|
.Vt BIO
|
|
first.
|
|
.Pp
|
|
Applications do not have to call
|
|
.Fn BIO_do_handshake
|
|
but may wish to do so to separate the handshake process from other I/O
|
|
processing.
|
|
.Pp
|
|
.Fn BIO_set_ssl ,
|
|
.Fn BIO_get_ssl ,
|
|
.Fn BIO_set_ssl_mode ,
|
|
.Fn BIO_set_ssl_renegotiate_bytes ,
|
|
.Fn BIO_set_ssl_renegotiate_timeout ,
|
|
.Fn BIO_get_num_renegotiates ,
|
|
and
|
|
.Fn BIO_do_handshake
|
|
are implemented as macros.
|
|
.Sh RETURN VALUES
|
|
.Fn BIO_f_ssl
|
|
returns a pointer to a static
|
|
.Vt BIO_METHOD
|
|
structure.
|
|
.Pp
|
|
When called on an SSL BIO object,
|
|
.Xr BIO_method_type 3
|
|
returns the constant
|
|
.Dv BIO_TYPE_SSL
|
|
and
|
|
.Xr BIO_method_name 3
|
|
returns a pointer to the static string
|
|
.Qq ssl .
|
|
.Pp
|
|
.Fn BIO_set_ssl ,
|
|
.Fn BIO_get_ssl ,
|
|
.Fn BIO_set_ssl_mode ,
|
|
.Fn BIO_set_ssl_renegotiate_bytes ,
|
|
.Fn BIO_set_ssl_renegotiate_timeout ,
|
|
and
|
|
.Fn BIO_get_num_renegotiates
|
|
return 1 on success or a value less than or equal to 0
|
|
if an error occurred.
|
|
.Pp
|
|
.Fn BIO_new_ssl ,
|
|
.Fn BIO_new_ssl_connect ,
|
|
and
|
|
.Fn BIO_new_buffer_ssl_connect
|
|
returns a pointer to a newly allocated
|
|
.Vt BIO
|
|
chain or
|
|
.Dv NULL
|
|
if an error occurred.
|
|
.Pp
|
|
.Fn BIO_ssl_copy_session_id
|
|
returns 1 on success or 0 on error.
|
|
.Pp
|
|
.Fn BIO_do_handshake
|
|
returns 1 if the connection was established successfully
|
|
or a value less than or equal to 0 otherwise.
|
|
.Sh EXAMPLES
|
|
This SSL/TLS client example attempts to retrieve a page from an SSL/TLS web
|
|
server.
|
|
The I/O routines are identical to those of the unencrypted example in
|
|
.Xr BIO_s_connect 3 .
|
|
.Bd -literal
|
|
BIO *sbio, *out;
|
|
int len;
|
|
char tmpbuf[1024];
|
|
SSL_CTX *ctx;
|
|
SSL *ssl;
|
|
|
|
ERR_load_crypto_strings();
|
|
ERR_load_SSL_strings();
|
|
OpenSSL_add_all_algorithms();
|
|
|
|
/*
|
|
* We would seed the PRNG here if the platform didn't do it automatically
|
|
*/
|
|
|
|
ctx = SSL_CTX_new(SSLv23_client_method());
|
|
|
|
/*
|
|
* We'd normally set some stuff like the verify paths and mode here because
|
|
* as things stand this will connect to any server whose certificate is
|
|
* signed by any CA.
|
|
*/
|
|
|
|
sbio = BIO_new_ssl_connect(ctx);
|
|
|
|
BIO_get_ssl(sbio, &ssl);
|
|
|
|
if (!ssl) {
|
|
fprintf(stderr, "Can't locate SSL pointer\en");
|
|
/* whatever ... */
|
|
}
|
|
|
|
/* Don't want any retries */
|
|
SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
|
|
|
|
/* We might want to do other things with ssl here */
|
|
|
|
BIO_set_conn_hostname(sbio, "localhost: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);
|
|
/* whatever ... */
|
|
}
|
|
|
|
if (BIO_do_handshake(sbio) <= 0) {
|
|
fprintf(stderr, "Error establishing SSL connection\en");
|
|
ERR_print_errors_fp(stderr);
|
|
/* whatever ... */
|
|
}
|
|
|
|
/* 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);
|
|
.Ed
|
|
.Pp
|
|
Here is a simple server example.
|
|
It makes use of a buffering
|
|
.Vt BIO
|
|
to allow lines to be read from the
|
|
.Vt SSL
|
|
.Vt BIO
|
|
using
|
|
.Xr BIO_gets 3 .
|
|
It creates a pseudo web page containing the actual request from a client and
|
|
also echoes the request to standard output.
|
|
.Bd -literal
|
|
BIO *sbio, *bbio, *acpt, *out;
|
|
int len;
|
|
char tmpbuf[1024];
|
|
SSL_CTX *ctx;
|
|
SSL *ssl;
|
|
|
|
ctx = SSL_CTX_new(SSLv23_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);
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Might do other things here like setting verify locations and DH and/or
|
|
* RSA temporary key callbacks
|
|
*/
|
|
|
|
/* New SSL BIO setup as server */
|
|
sbio = BIO_new_ssl(ctx,0);
|
|
|
|
BIO_get_ssl(sbio, &ssl);
|
|
|
|
if (!ssl) {
|
|
fprintf(stderr, "Can't locate SSL pointer\en");
|
|
/* whatever ... */
|
|
}
|
|
|
|
/* Don't want any retries */
|
|
SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
|
|
|
|
/* Create the buffering BIO */
|
|
|
|
bbio = BIO_new(BIO_f_buffer());
|
|
|
|
/* Add to chain */
|
|
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 'swallowed' 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);
|
|
|
|
/* Wait for incoming connection */
|
|
if (BIO_do_accept(acpt) <= 0) {
|
|
fprintf(stderr, "Error setting up accept BIO\en");
|
|
ERR_print_errors_fp(stderr);
|
|
return 0;
|
|
}
|
|
|
|
/* 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);
|
|
return 0;
|
|
}
|
|
|
|
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] == '\er') || (tmpbuf[0] == '\en'))
|
|
break;
|
|
}
|
|
|
|
BIO_puts(sbio, "--------------------------------------------------\er\en");
|
|
BIO_puts(sbio, "\er\en");
|
|
|
|
/* Since there is a buffering BIO present we had better flush it */
|
|
BIO_flush(sbio);
|
|
|
|
BIO_free_all(sbio);
|
|
.Ed
|
|
.Sh SEE ALSO
|
|
.Xr BIO_new 3 ,
|
|
.Xr ssl 3
|
|
.Sh HISTORY
|
|
.Fn BIO_f_ssl ,
|
|
.Fn BIO_set_ssl ,
|
|
and
|
|
.Fn BIO_get_ssl
|
|
first appeared in SSLeay 0.6.0.
|
|
.Fn BIO_set_ssl_mode ,
|
|
.Fn BIO_new_ssl ,
|
|
and
|
|
.Fn BIO_ssl_copy_session_id
|
|
first appeared in SSLeay 0.8.0.
|
|
.Fn BIO_ssl_shutdown
|
|
and
|
|
.Fn BIO_do_handshake
|
|
first appeared in SSLeay 0.8.1.
|
|
.Fn BIO_set_ssl_renegotiate_bytes ,
|
|
.Fn BIO_get_num_renegotiates ,
|
|
.Fn BIO_set_ssl_renegotiate_timeout ,
|
|
.Fn BIO_new_ssl_connect ,
|
|
and
|
|
.Fn BIO_new_buffer_ssl_connect
|
|
first appeared in SSLeay 0.9.0.
|
|
All these functions have been available since
|
|
.Ox 2.4 .
|