8 releases

0.5.1 May 2, 2022
0.5.0 May 20, 2021
0.4.0 May 5, 2021
0.3.3 Apr 28, 2021
0.2.0 Jan 14, 2021

#983 in Cryptography

Download history 141/week @ 2024-02-26 70/week @ 2024-03-04 59/week @ 2024-03-11 91/week @ 2024-03-18 90/week @ 2024-03-25 223/week @ 2024-04-01 18/week @ 2024-04-08 61/week @ 2024-04-15 57/week @ 2024-04-22 139/week @ 2024-04-29 81/week @ 2024-05-06 178/week @ 2024-05-13 106/week @ 2024-05-20 55/week @ 2024-05-27 31/week @ 2024-06-03 45/week @ 2024-06-10

246 downloads per month
Used in agnos

MIT license



A Tokio and OpenSSL based ACMEv2 client.


  • ACME v2 support, tested against Let's Encrypt and Pebble
  • Fully async, using reqwest / Tokio
  • Support for DNS01 and HTTP01 validation
  • Fully instrumented with tracing


This example demonstrates how to provision a certificate for the domain example.com using http-01 validation.

use acme2::gen_rsa_private_key;
use acme2::AccountBuilder;
use acme2::AuthorizationStatus;
use acme2::ChallengeStatus;
use acme2::DirectoryBuilder;
use acme2::Error;
use acme2::OrderBuilder;
use acme2::OrderStatus;
use acme2::Csr;
use std::time::Duration;

const LETS_ENCRYPT_URL: &'static str =

async fn main() -> Result<(), Error> {
  // Create a new ACMEv2 directory for Let's Encrypt.
  let dir = DirectoryBuilder::new(LETS_ENCRYPT_URL.to_string())

  // Create an ACME account to use for the order. For production
  // purposes, you should keep the account (and private key), so
  // you can renew your certificate easily.
  let mut builder = AccountBuilder::new(dir.clone());
  let account = builder.build().await?;

  // Create a new order for a specific domain name.
  let mut builder = OrderBuilder::new(account);
  let order = builder.build().await?;

  // Get the list of needed authorizations for this order.
  let authorizations = order.authorizations().await?;
  for auth in authorizations {
    // Get an http-01 challenge for this authorization (or panic
    // if it doesn't exist).
    let challenge = auth.get_challenge("http-01").unwrap();

    // At this point in time, you must configure your webserver to serve
    // a file at `https://example.com/.well-known/${challenge.token}`
    // with the content of `challenge.key_authorization()??`.

    // Start the validation of the challenge.
    let challenge = challenge.validate().await?;

    // Poll the challenge every 5 seconds until it is in either the
    // `valid` or `invalid` state.
    let challenge = challenge.wait_done(Duration::from_secs(5), 3).await?;

    assert_eq!(challenge.status, ChallengeStatus::Valid);

    // You can now remove the challenge file hosted on your webserver.

    // Poll the authorization every 5 seconds until it is in either the
    // `valid` or `invalid` state.
    let authorization = auth.wait_done(Duration::from_secs(5), 3).await?;
    assert_eq!(authorization.status, AuthorizationStatus::Valid)

  // Poll the order every 5 seconds until it is in either the
  // `ready` or `invalid` state. Ready means that it is now ready
  // for finalization (certificate creation).
  let order = order.wait_ready(Duration::from_secs(5), 3).await?;

  assert_eq!(order.status, OrderStatus::Ready);

  // Generate an RSA private key for the certificate.
  let pkey = gen_rsa_private_key(4096)?;

  // Create a certificate signing request for the order, and request
  // the certificate.
  let order = order.finalize(Csr::Automatic(pkey)).await?;

  // Poll the order every 5 seconds until it is in either the
  // `valid` or `invalid` state. Valid means that the certificate
  // has been provisioned, and is now ready for download.
  let order = order.wait_done(Duration::from_secs(5), 3).await?;

  assert_eq!(order.status, OrderStatus::Valid);

  // Download the certificate, and panic if it doesn't exist.
  let cert = order.certificate().await?.unwrap();
  assert!(cert.len() > 1);



To run the tests, you will need to install pebble and pebble-challtestsrv.

Start these before running the tests with these commands (in seperate shells):

pebble -config ./pebble-config.json -strict


To compile on Windows you will need OpenSSL. Here is an easy way to get it installed.

(example in Git Bash)

git clone https://github.com/microsoft/vcpkg
cd vcpkg
./vcpkg.exe install openssl
./vcpkg.exe install openssl:x64-windows-static
# Add OPENSSL_DIR=/vcpkg/path/installed/x64-windows-static
cargo build


This project is licenced under MIT. See LICENCE file for more.


~333K SLoC