#acme-client #acme #证书 #letsencrypt #openssl #tokio #账户

acme2-eab

基于Tokio和OpenSSL的ACMEv2客户端

6个版本

0.5.6 2024年7月17日
0.5.5 2024年3月9日
0.5.4 2023年12月5日
0.5.3 2023年6月16日
0.5.1 2022年8月10日

#314加密学

Download history 32/week @ 2024-04-26 61/week @ 2024-05-03 54/week @ 2024-05-10 29/week @ 2024-05-17 104/week @ 2024-05-24 57/week @ 2024-05-31 29/week @ 2024-06-07 70/week @ 2024-06-14 81/week @ 2024-06-21 57/week @ 2024-06-28 80/week @ 2024-07-05 186/week @ 2024-07-12 106/week @ 2024-07-19 94/week @ 2024-07-26 80/week @ 2024-08-02 53/week @ 2024-08-09

每月371次下载
用于 2 crates

MIT许可证

57KB
1K SLoC

注意:这是 lucacasonato/acme2 的分支,增加了对 外部账户绑定 的支持,这是ZeroSSL和Google证书管理器支持所需的。它被单独打包,以便我们可以在合并 这个上游PR 之前从其他代码库中使用它。

acme2

一个基于TokioOpenSSLACMEv2客户端。

特性

  • ACME v2支持,针对Let's Encrypt和Pebble进行了测试
  • 完全异步,使用reqwest / Tokio
  • 支持DNS01和HTTP01验证
  • 完全使用tracing进行仪表化

示例

此示例演示了如何使用http-01验证为example.com域名提供证书。

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 =
  "https://acme-v02.api.letsencrypt.org/directory";

#[tokio::main]
async fn main() -> Result<(), Error> {
  // Create a new ACMEv2 directory for Let's Encrypt.
  let dir = DirectoryBuilder::new(LETS_ENCRYPT_URL.to_string())
    .build()
    .await?;

  // 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());
  builder.contact(vec!["mailto:[email protected]".to_string()]);
  builder.terms_of_service_agreed(true);
  let account = builder.build().await?;

  // Create a new order for a specific domain name.
  let mut builder = OrderBuilder::new(account);
  builder.add_dns_identifier("example.com".to_string());
  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);

  Ok(())
}

开发

要运行测试,您需要一个正在运行的Docker实例。然后,运行

cargo test

许可证

本项目采用MIT许可证。有关更多信息,请参阅LICENCE文件。

依赖关系

~8–23MB
~303K SLoC