1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
//! rustls-acme is an easy-to-use, async compatible ACME client library for rustls.
//! The validation mechanism used is tls-alpn-01, which allows serving acme challenge responses and
//! regular TLS traffic on the same port.
//!
//! rustls-acme is designed to be runtime agnostic and as runtime independent as Rust allows at the
//! moment.
//! No persistent tasks are spawned under the hood and the certificate acquisition/renewal process
//! is folded into the streams and futures being polled by the library user.
//!
//! The goal is to provide a [Let's Encrypt](https://letsencrypt.org/) compatible TLS serving and
//! certificate management using a simple and flexible stream based API.
//!
//! To use rustls-acme add the following lines to your `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! rustls-acme = "*"
//! ```
//!
//! ## High-level API
//!
//! The high-level API consists of a single stream [Incoming] of incoming TLS connection.
//! Polling the next future of the stream takes care of acquisition and renewal of certificates, as
//! well as accepting TLS connections, which are handed over to the caller on success.
//!
//! ```rust,no_run
//! use futures::prelude::*;
//! use rustls_acme::{AcmeConfig, caches::DirCache};
//!
//! #[smol_potat::main]
//! async fn main() {
//!     simple_logger::init_with_level(log::Level::Info).unwrap();
//!
//!     let tcp_listener = smol::net::TcpListener::bind("[::]:443").await.unwrap();
//!
//!     let mut tls_incoming = AcmeConfig::new(["example.com"])
//!         .contact_push("mailto:admin@example.com")
//!         .cache(DirCache::new("./rustls_acme_cache"))
//!         .incoming(tcp_listener.incoming());
//!
//!     while let Some(tls) = tls_incoming.next().await {
//!         let mut tls = tls.unwrap();
//!         smol::spawn(async move {
//!             tls.write_all(HELLO).await.unwrap();
//!             tls.close().await.unwrap();
//!         }).detach();
//!     }
//! }
//!
//! const HELLO: &'static [u8] = br#"HTTP/1.1 200 OK
//! Content-Length: 11
//! Content-Type: text/plain; charset=utf-8
//!
//! Hello Tls!"#;
//! ```
//!
//! The server_simple example is a "Hello Tls!" server similar to the one above which accepts
//! domain, port and cache directory parameters.
//!
//! Note that all examples use the let's encrypt staging directory by default.
//! The production directory imposes strict rate limits, which are easily exhausted accidentally
//! during testing and development.
//! For testing with the staging directory you may open `https://<your domain>:<port>` in a browser
//! that allows TLS connection to servers signed by an untrusted CA (in Firefox click "Advanced..."
//! -> "Accept the Risk and Continue").
//!
//! ## Low-level Rustls API
//!
//! For users who may want to interact with [rustls](async_rustls::rustls) or [async_rustls]
//! directly, the library exposes the underlying certificate management [AcmeState] as well as a
//! matching resolver [ResolvesServerCertAcme] which implements the
//! [rustls::ResolvesServerCert](async_rustls::rustls::ResolvesServerCert) trait.
//! See the server_low_level example on how to use the low-level API directly with async-rustls.
//!
//! ## Account and certificate caching
//!
//! A production server using the let's encrypt production directory must implement both account and
//! certificate caching to avoid exhausting the let's encrypt API rate limits.
//! A file based cache using a cache directory is provided by [caches::DirCache].
//! Caches backed by other persistence layers may be implemented using the [Cache] trait,
//! or the underlying [CertCache], [AccountCache] traits (contributions welcome).
//! [caches::CompositeCache] provides a wrapper to combine two implementors of [CertCache] and
//! [AccountCache] into a single [Cache].
//!
//! Note, that the error type parameters of the cache carries over to some other types in this
//! crate via the [AcmeConfig] they are added to.
//! If you want to avoid different specializations based on cache type use the
//! [AcmeConfig::cache_with_boxed_err] method to construct the an [AcmeConfig] object.
//!
//!
//! ## The acme module
//!
//! The underlying implementation of an async acme client may be useful to others and is exposed as
//! a module. It is incomplete (contributions welcome) and not covered by any stability
//! promises.
//!
//! ## Special thanks
//!
//! This crate was inspired by the [autocert](https://golang.org/x/crypto/acme/autocert/)
//! package for [Go](https://golang.org).
//!
//! This crate builds on the excellent work of the authors of
//! [rustls](https://github.com/ctz/rustls),
//! [async-rustls](https://github.com/smol-rs/async-rustls),
//! and many others.
//!
//! Thanks to [Josh Triplett](https://github.com/joshtriplett) for contributions and feedback.

pub mod acme;
mod cache;
pub mod caches;
mod config;
mod https_helper;
mod incoming;
mod jose;
mod resolver;
mod state;

pub use cache::*;
pub use config::*;
pub use incoming::*;
pub use resolver::*;
pub use state::*;