Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: various small fixes to the README documentation #355

Merged
merged 10 commits into from
Oct 17, 2023
61 changes: 31 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,23 @@ It also contains demo C programs that use those bindings to run an HTTPS server,
make an HTTPS request.

Rustls is a modern TLS library written in Rust, meaning it is less likely to
have memory safety vulnerabilities that equivalent TLS libraries written in
have memory safety vulnerabilities than equivalent TLS libraries written in
memory unsafe languages.

If you are using rustls-ffi to replace OpenSSL, note that OpenSSL provides
[cryptographic primitives](https://www.openssl.org/docs/man3.0/man7/crypto.html)
in addition to a TLS library. Rustls-ffi only provides the TLS library. If you
use the cryptographic primitives from OpenSSL you may need to
need to find another library to provide the cryptographic primitives.
use the cryptographic primitives from OpenSSL you may need to find another library
to provide the cryptographic primitives.

# Build

You'll need to [install the Rust toolchain](https://rustup.rs/) version 1.60
or above and a C compiler (gcc and clang should both work). To build in optimized mode:
You'll need to [install the Rust toolchain](https://rustup.rs/) (version 1.61
or above) and a C compiler (`gcc` and `clang` should both work). To build in optimized mode:

make

To install in /usr/local/:
To install in `/usr/local/`:

sudo make install

Expand Down Expand Up @@ -56,8 +56,8 @@ supports.

# Conventions

This library defines an enum, rustls_result, to indicate success or failure of
a function call. All fallible functions return a rustls_result. If a function
This library defines an `enum`, `rustls_result`, to indicate success or failure of
a function call. All fallible functions return a `rustls_result`. If a function
has other outputs, it provides them using output parameters (pointers to
caller-provided objects). For instance:

Expand Down Expand Up @@ -94,9 +94,9 @@ mutating.
## Input and Output Parameters

Input parameters will always be either a const pointer or a primitive type
(int, size_t, etc). Output parameters will always be a non-const pointer.
(`int`, `size_t`, etc). Output parameters will always be a non-const pointer.

The caller is responsible for ensuring that the memory pointed to be output
The caller is responsible for ensuring that the memory pointed to by output
parameters is not being concurrently accessed by other threads. For primitive
types and pointers-to-pointers this is most commonly accomplished by passing
the address of a local variable on the stack that has no references elsewhere.
Expand All @@ -108,15 +108,15 @@ the caller will need to take additional steps to prevent concurrent access
When an output parameter is a pointer to a pointer (e.g.
`rustls_connection **conn_out`, the function will set its argument
to point to an appropriate object on success. The caller is considered to take
ownership of that object and be responsible for the requirements above:
ownership of that object and must be responsible for the requirements above:
preventing concurrent mutation, and freeing it exactly once.

For a method, the first parameter will always be a pointer to the struct being
operated on. Next will come some number of input parameters, then some number
of output parameters.

As a minor exception to the above: When an output parameter is a byte buffer
(*uint8_t), the next parameter will always be a size_t denoting the size of
(`*uint8_t`), the next parameter will always be a `size_t` denoting the size of
the buffer. This is considered part of the output parameters even though it is
not directly modified.

Expand All @@ -133,31 +133,31 @@ pointed to by output arguments.
Rustls supports various types of user customization via callbacks. All callbacks
take a `void *userdata` parameter as their first parameter. Unless otherwise
specified, this will receive a value that was associated with a
rustls_connection via `rustls_connection_set_userdata`. If no such value was
set, they will receive NULL. The read and write callbacks are a particular
`rustls_connection` via `rustls_connection_set_userdata`. If no such value was
set, they will receive `NULL`. The read and write callbacks are a particular
exception to this rule - they receive a userdata value passed through from the
current call to rustls_connection_{read,write}_tls.
current call to `rustls_connection_{read,write}_tls`.

## NULL

The library checks all pointers in arguments for NULL and will return an error
rather than dereferencing a NULL pointer. For some methods that are infallible
except for the possibility of NULL (for instance
The library checks all pointers in arguments for `NULL` and will return an error
rather than dereferencing a `NULL` pointer. For some methods that are infallible
except for the possibility of `NULL` (for instance
`rustls_connection_is_handshaking`), the library returns a convenient
type (e.g. `bool`) and uses a suitable fallback value if an input is NULL.
type (e.g. `bool`) and uses a suitable fallback value if an input is `NULL`.

## Panics

In case of a bug (e.g. exceeding the bounds of an array), Rust code may
emit a panic. Panics are treated like exceptions in C++, unwinding the stack.
Unwinding past the FFI boundary is undefined behavior, so this library catches
all unwinds and turns them into RUSTLS_RESULT_PANIC (when the function is
all unwinds and turns them into `RUSTLS_RESULT_PANIC` (when the function is
fallible).

Functions that are theoretically infallible don't return rustls_result, so we
can't return RUSTLS_RESULT_PANIC. In those cases, if there's a panic, we'll
return a default value suitable to the return type: NULL for pointer types,
false for bool types, and 0 for integer types.
Functions that are theoretically infallible don't return `rustls_result`, so we
can't return `RUSTLS_RESULT_PANIC`. In those cases, if there's a panic, we'll
return a default value suitable to the return type: `NULL` for pointer types,
`false` for bool types, and `0` for integer types.

# Experimentals

Expand All @@ -169,7 +169,7 @@ need further evaluation and will most likely change significantly in the future.
The `rustls_server_config_builder_set_hello_callback` and its provided information
in `rustls_client_hello` will change. The current design is a snapshot of the
implementation efforts in [mod_tls](https://github.com/icing/mod_tls) to provide
`rustls` base TLS as module for the Apache webserver.
`rustls`-based TLS as module for the Apache webserver.

For a webserver hosting multiple domains on the same endpoint, it is highly desirable
to have individual TLS settings, depending on the domain the client wants to talk to.
Expand Down Expand Up @@ -198,17 +198,18 @@ create the one with the correct setting for the domain chosen.

For this to work, your connection needs to buffer the initial data from the
client, so these bytes can be replayed to the second connection you use. Do not
write any data back to the client while your are in the initial connection. The
write any data back to the client while you are in the initial connection. The
client hellos are usually only a few hundred bytes.

#### Verifying TLS certificates

By default, rustls does not load any TLS certificates, not even the system
store, which means that TLS certificate verification will fail by default. You
are responsible for loading certificates using one of the following methods:
By default, rustls does not load any trust anchors (root certificates), not even
the system trust anchor store, which means that TLS certificate verification will
fail by default. You are responsible for loading certificates using one of the
following methods:

- `rustls_root_cert_store_add_pem`, which adds a single certificate to a root
store
store.

- `rustls_client_config_builder_load_roots_from_file`, which loads certificates
from a file.
Expand Down