<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;"># NAME

Net::ACME2 - Client logic for the ACME (Let窶冱 Encrypt) protocol

  

# SYNOPSIS

    package SomeCA::ACME;

    use parent qw( Net::ACME2 );

    use constant {
        DIRECTORY_PATH =&gt; '/acme-directory',
    };

    # %opts are the parameters given to new().
    sub HOST {
        my ($class, %opts) = @_;

        # You can make this depend on the %opts if you want.
        return 'acme.someca.net';
    }

    package main;

    my $acme = SomeCA::ACME-&gt;new(
        key =&gt; $account_key_pem_or_der,
        key_id =&gt; undef,
    );

    #for a new account
    {
        my $terms_url = $acme-&gt;get_terms_of_service();

        $acme-&gt;create_account(
            termsOfServiceAgreed =&gt; 1,
        );
    }

    #Save $acme-&gt;key_id() somewhere so you can use it again.

    my $order = $acme-&gt;create_order(
        identifiers =&gt; [
            { type =&gt; 'dns', value =&gt; '*.example.com' },
        ],
    );

    my $authz = $acme-&gt;get_authorization( ($order-&gt;authorizations())[0] );

    my @challenges = $authz-&gt;challenges();

    # ... Pick a challenge, and satisfy it.

    $acme-&gt;accept_challenge($challenge);

    sleep 1 while 'valid' ne $acme-&gt;poll_authorization($authz);

    # ... Make a key and CSR for *.example.com

    $acme-&gt;finalize_order($order, $csr_pem_or_der);

    while ($order-&gt;status() ne 'valid') {
        sleep 1;
        $acme-&gt;poll_order($order);
    }

    # ... and now fetch the certificate chain:

    my $pem_chain = $acme-&gt;get_certificate_chain($order);

See `/examples` in the distribution for more fleshed-out examples.

To use [Let窶冱 Encrypt](http://letsencrypt.org), see
[Net::ACME2::LetsEncrypt](https://metacpan.org/pod/Net::ACME2::LetsEncrypt).

# DESCRIPTION

This library implements client logic for the
ACME (Automated Certificate Management Environment) protocol, as
standardized in [RFC 8555](https://www.rfc-editor.org/rfc/rfc8555.txt)
and popularized by [Let窶冱 Encrypt](http://letsencrypt.org).

# STATUS

This is a production-grade implementation. While breaking changes at this
point are unlikely, please always check the changelog before upgrading to
a new version of this module.

# FEATURES

- Support for both ECDSA and RSA encrytion.
- Support for http-01, dns-01, and [tls-alpn-01](https://datatracker.ietf.org/doc/draft-ietf-acme-tls-alpn/) challenges.
- Comprehensive error handling with typed, [X::Tiny](https://metacpan.org/pod/X::Tiny)-based exceptions.
- This is a pure-Perl solution. Most of its dependencies are
either core modules or pure Perl themselves. XS is necessary to
communicate with the ACME server via TLS; however, most Perl installations
already include the necessary logic (i.e., [Net::SSLeay](https://metacpan.org/pod/Net::SSLeay)) for TLS.

    In short, Net::ACME2 will run anywhere that Perl can speak TLS, which is
    _almost_ everywhere that Perl runs.

# ERROR HANDLING

All thrown exceptions are instances of [Net::ACME2::X::Base](https://metacpan.org/pod/Net::ACME2::X::Base).
Specific error classes aren窶冲 yet defined.

# SPEED

If you notice speed problems, check to see if your [Math::BigInt](https://metacpan.org/pod/Math::BigInt)
installation can be made faster.

# METHODS

## _CLASS_-&gt;new( %OPTS )

Instantiates an ACME2 object, which you窶冤l use for all
interactions with the ACME server. %OPTS is:

- `key` - Required. The private key to associate with the ACME2
user. Anything that `Crypt::Perl::PK::parse_key()` can parse is acceptable.
- `key_id` - Optional. As returned by `key_id()`.
Saves a round-trip to the ACME2 server, so you should give this
if you have it.
- `directory` - Optional. A hash reference to use as the
directory contents. Saves a round-trip to the ACME2 server, but there窶冱
no built-in logic to determine when the cache goes invalid. Caveat
emptor.

## $id = _OBJ_-&gt;key\_id()

Returns the object窶冱 cached key ID, either as given at instantiation
or as fetched in `create_account()`.

## $url = _OBJ_-&gt;get\_terms\_of\_service()

Returns the URL for the terms of service.

**NOTE:** For [Let窶冱 Encrypt](http://letsencrypt.org) you can
unofficially resolve against
[https://acme-v01.api.letsencrypt.org/terms](https://acme-v01.api.letsencrypt.org/terms) to see the terms
of service.

## $created\_yn = _OBJ_-&gt;create\_account( %OPTS )

Creates an account using the ACME2 object窶冱 key and the passed
%OPTS, which are as described in the ACME2 spec (cf. `newAccount`).
Boolean values may be given as simple Perl booleans.

Returns 1 if the account is newly created
or 0 if the account already existed.

NB: `create_new_account()` is an alias for this method.

## $order = _OBJ_-&gt;create\_order( %OPTS )

Returns a [Net::ACME2::Order](https://metacpan.org/pod/Net::ACME2::Order) object. %OPTS is as described in the
ACME spec (cf. `newOrder`). Boolean values may be given as simple
Perl booleans.

NB: `create_new_order()` is an alias for this method.

## $authz = _OBJ_-&gt;get\_authorization( $URL )

Fetches the authorization窶冱 information based on the given $URL
and returns a [Net::ACME2::Authorization](https://metacpan.org/pod/Net::ACME2::Authorization) object.

The URL is as given by [Net::ACME2::Order](https://metacpan.org/pod/Net::ACME2::Order)窶冱 `authorizations()` method.

## $str = _OBJ_-&gt;make\_key\_authorization( $CHALLENGE )

Accepts an instance of [Net::ACME2::Challenge](https://metacpan.org/pod/Net::ACME2::Challenge) (probably a subclass
thereof) and returns
a key authorization string suitable for handling the given $CHALLENGE.
See `/examples` in the distribution for example usage.

If you窶决e using HTTP authorization and are on the same server as the
domains窶� document roots, then look at the handler logic in
[Net::ACME2::Challenge::http\_01](https://metacpan.org/pod/Net::ACME2::Challenge::http_01) for a potentially simpler way to
handle HTTP challenges.

## _OBJ_-&gt;accept\_challenge( $CHALLENGE )

Signal to the ACME server that the CHALLENGE is ready.

## $status = _OBJ_-&gt;poll\_authorization( $AUTHORIZATION )

Accepts a [Net::ACME2::Authorization](https://metacpan.org/pod/Net::ACME2::Authorization) instance and polls the
ACME server for that authorization窶冱 status. The $AUTHORIZATION
object is then updated with the results of the poll.

As a courtesy, this returns the $AUTHORIZATION窶冱 new `status()`.

## $status = _OBJ_-&gt;finalize\_order( $ORDER, $CSR )

Finalizes an order and updates the $ORDER object with the returned
status. $CSR may be in either DER or PEM format.

As a courtesy, this returns the $ORDER窶冱 `status()`. If this does
not equal `valid`, then you should probably `poll_order()`
until it does.

## $status = _OBJ_-&gt;poll\_order( $ORDER )

Like `poll_authorization()` but handles a
[Net::ACME2::Order](https://metacpan.org/pod/Net::ACME2::Order) object instead.

## $cert = _OBJ_-&gt;get\_certificate\_chain( $ORDER )

Fetches the $ORDER窶冱 certificate chain and returns
it in the format implied by the
`application/pem-certificate-chain` MIME type. See the ACME
protocol specification for details about this format.

# TODO

- Add pre-authorization support if there is ever a production
use for it.
- Expose the Retry-After header via the module API.
- There is currently no way to fetch an order or challenge窶冱
properties via URL. Prior to ACME窶冱 adoption of 窶弃OST-as-GET窶� this was
doable via a plain GET to the URL, but that窶冱 no longer possible.
If there窶冱 a need, I窶冤l consider adding such logic to Net::ACME2.
(It窶冱 trivial to add; I窶囘 just like to keep things as
simple as possible.)
- Add (more) tests.

# SEE ALSO

[Crypt::Perl](https://metacpan.org/pod/Crypt::Perl) provides this library窶冱 cryptography backend. See
this distribution窶冱 `/examples` directory for sample usage
to generate keys and CSRs.

[Net::ACME](https://metacpan.org/pod/Net::ACME) implements client logic for the variant of this
protocol that Let窶冱 Encrypt first deployed.
</pre></body></html>