• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

examples/H13-Apr-2020-418265

lib/Net/H13-Apr-2020-2,8781,247

t/H13-Apr-2020-839597

.gitignoreH A D13-Jan-2018328 3830

.travis.ymlH A D13-Apr-2020479 2423

ChangesH A D13-Apr-20205.9 KiB157127

LICENSEH A D25-Aug-201820.1 KiB384309

MANIFESTH A D13-Apr-20201.4 KiB5352

META.jsonH A D13-Apr-20202 KiB7776

META.ymlH A D13-Apr-20201.1 KiB4746

Makefile.PLH A D13-Apr-20201.8 KiB5546

README.mdH A D13-Apr-20208.7 KiB254171

eval_bug.readmeH A D23-Jun-2018257 1110

README.md

1# NAME
2
3Net::ACME2 - Client logic for the ACME (Let's Encrypt) protocol
4
5
6
7# SYNOPSIS
8
9    package SomeCA::ACME;
10
11    use parent qw( Net::ACME2 );
12
13    use constant {
14        DIRECTORY_PATH => '/acme-directory',
15    };
16
17    # %opts are the parameters given to new().
18    sub HOST {
19        my ($class, %opts) = @_;
20
21        # You can make this depend on the %opts if you want.
22        return 'acme.someca.net';
23    }
24
25    package main;
26
27    my $acme = SomeCA::ACME->new(
28        key => $account_key_pem_or_der,
29        key_id => undef,
30    );
31
32    #for a new account
33    {
34        my $terms_url = $acme->get_terms_of_service();
35
36        $acme->create_account(
37            termsOfServiceAgreed => 1,
38        );
39    }
40
41    #Save $acme->key_id() somewhere so you can use it again.
42
43    my $order = $acme->create_order(
44        identifiers => [
45            { type => 'dns', value => '*.example.com' },
46        ],
47    );
48
49    my $authz = $acme->get_authorization( ($order->authorizations())[0] );
50
51    my @challenges = $authz->challenges();
52
53    # ... Pick a challenge, and satisfy it.
54
55    $acme->accept_challenge($challenge);
56
57    sleep 1 while 'valid' ne $acme->poll_authorization($authz);
58
59    # ... Make a key and CSR for *.example.com
60
61    $acme->finalize_order($order, $csr_pem_or_der);
62
63    while ($order->status() ne 'valid') {
64        sleep 1;
65        $acme->poll_order($order);
66    }
67
68    # ... and now fetch the certificate chain:
69
70    my $pem_chain = $acme->get_certificate_chain($order);
71
72See `/examples` in the distribution for more fleshed-out examples.
73
74To use [Let’s Encrypt](http://letsencrypt.org), see
75[Net::ACME2::LetsEncrypt](https://metacpan.org/pod/Net::ACME2::LetsEncrypt).
76
77# DESCRIPTION
78
79This library implements client logic for the
80ACME (Automated Certificate Management Environment) protocol, as
81standardized in [RFC 8555](https://www.rfc-editor.org/rfc/rfc8555.txt)
82and popularized by [Let’s Encrypt](http://letsencrypt.org).
83
84# STATUS
85
86This is a production-grade implementation. While breaking changes at this
87point are unlikely, please always check the changelog before upgrading to
88a new version of this module.
89
90# FEATURES
91
92- Support for both ECDSA and RSA encrytion.
93- Support for http-01, dns-01, and [tls-alpn-01](https://datatracker.ietf.org/doc/draft-ietf-acme-tls-alpn/) challenges.
94- Comprehensive error handling with typed, [X::Tiny](https://metacpan.org/pod/X::Tiny)-based exceptions.
95- [Retry POST on `badNonce` errors.](https://tools.ietf.org/html/rfc8555#section-6.5)
96- This is a pure-Perl solution. Most of its dependencies are
97either core modules or pure Perl themselves. XS is necessary to
98communicate with the ACME server via TLS; however, most Perl installations
99already include the necessary logic (i.e., [Net::SSLeay](https://metacpan.org/pod/Net::SSLeay)) for TLS.
100
101    In short, Net::ACME2 will run anywhere that Perl can speak TLS, which is
102    _almost_ everywhere that Perl runs.
103
104# ERROR HANDLING
105
106All thrown exceptions are instances of [Net::ACME2::X::Generic](https://metacpan.org/pod/Net::ACME2::X::Generic).
107Specific error classes aren’t yet defined.
108
109# CRYPTOGRAPHY & SPEED
110
111[Crypt::Perl](https://metacpan.org/pod/Crypt::Perl) provides all cryptographic operations that this library
112needs using pure Perl. While this satisfies this module’s intent to be
113as pure-Perl as possible, there are a couple of significant drawbacks
114to this approach: firstly, it’s slower than XS-based code, and secondly,
115it loses the security benefits of the vetting that more widely-used
116cryptography libraries receive.
117
118To address these problems, Net::ACME2 will, after parsing a key, look
119for and prefer the following XS-based libraries for cryptography instead:
120
121- [Crypt::OpenSSL::RSA](https://metacpan.org/pod/Crypt::OpenSSL::RSA) (based on [OpenSSL](http://openssl.org))
122- [CryptX](https://metacpan.org/pod/CryptX) (based on [LibTomCrypt](http://www.libtom.net/LibTomCrypt/))
123
124If the above are unavailable to you, then you may be able to speed up
125your [Math::BigInt](https://metacpan.org/pod/Math::BigInt) installation; see that module’s documentation
126for more details.
127
128# METHODS
129
130## _CLASS_->new( %OPTS )
131
132Instantiates an ACME2 object, which you’ll use for all
133interactions with the ACME server. %OPTS is:
134
135- `key` - Required. The private key to associate with the ACME2
136user. Anything that `Crypt::Perl::PK::parse_key()` can parse is acceptable.
137- `key_id` - Optional. As returned by `key_id()`.
138Saves a round-trip to the ACME2 server, so you should give this
139if you have it.
140- `directory` - Optional. A hash reference to use as the
141directory contents. Saves a round-trip to the ACME2 server, but there’s
142no built-in logic to determine when the cache goes invalid. Caveat
143emptor.
144
145## $id = _OBJ_->key\_id()
146
147Returns the object’s cached key ID, either as given at instantiation
148or as fetched in `create_account()`.
149
150## _OBJ_->http\_timeout( \[$NEW\] )
151
152A passthrough interface to the underlying [HTTP::Tiny](https://metacpan.org/pod/HTTP::Tiny) object’s
153`timeout()` method.
154
155## $url = _CLASS_->get\_terms\_of\_service()
156
157Returns the URL for the terms of service. Callable as either
158a class method or an instance method.
159
160## $created\_yn = _OBJ_->create\_account( %OPTS )
161
162Creates an account using the ACME2 object’s key and the passed
163%OPTS, which are as described in the ACME2 spec (cf. `newAccount`).
164Boolean values may be given as simple Perl booleans.
165
166Returns 1 if the account is newly created
167or 0 if the account already existed.
168
169NB: `create_new_account()` is an alias for this method.
170
171## $order = _OBJ_->create\_order( %OPTS )
172
173Returns a [Net::ACME2::Order](https://metacpan.org/pod/Net::ACME2::Order) object. %OPTS is as described in the
174ACME spec (cf. `newOrder`). Boolean values may be given as simple
175Perl booleans.
176
177NB: `create_new_order()` is an alias for this method.
178
179## $authz = _OBJ_->get\_authorization( $URL )
180
181Fetches the authorization’s information based on the given $URL
182and returns a [Net::ACME2::Authorization](https://metacpan.org/pod/Net::ACME2::Authorization) object.
183
184The URL is as given by [Net::ACME2::Order](https://metacpan.org/pod/Net::ACME2::Order)’s `authorizations()` method.
185
186## $str = _OBJ_->make\_key\_authorization( $CHALLENGE )
187
188Accepts an instance of [Net::ACME2::Challenge](https://metacpan.org/pod/Net::ACME2::Challenge) (probably a subclass
189thereof) and returns
190a key authorization string suitable for handling the given $CHALLENGE.
191See `/examples` in the distribution for example usage.
192
193If you’re using HTTP authorization and are on the same server as the
194domains’ document roots, then look at the handler logic in
195[Net::ACME2::Challenge::http\_01](https://metacpan.org/pod/Net::ACME2::Challenge::http_01) for a potentially simpler way to
196handle HTTP challenges.
197
198## _OBJ_->accept\_challenge( $CHALLENGE )
199
200Signal to the ACME server that the CHALLENGE is ready.
201
202## $status = _OBJ_->poll\_authorization( $AUTHORIZATION )
203
204Accepts a [Net::ACME2::Authorization](https://metacpan.org/pod/Net::ACME2::Authorization) instance and polls the
205ACME server for that authorization’s status. The $AUTHORIZATION
206object is then updated with the results of the poll.
207
208As a courtesy, this returns the $AUTHORIZATION’s new `status()`.
209
210## $status = _OBJ_->finalize\_order( $ORDER, $CSR )
211
212Finalizes an order and updates the $ORDER object with the returned
213status. $CSR may be in either DER or PEM format.
214
215As a courtesy, this returns the $ORDER’s `status()`. If this does
216not equal `valid`, then you should probably `poll_order()`
217until it does.
218
219## $status = _OBJ_->poll\_order( $ORDER )
220
221Like `poll_authorization()` but handles a
222[Net::ACME2::Order](https://metacpan.org/pod/Net::ACME2::Order) object instead.
223
224## $cert = _OBJ_->get\_certificate\_chain( $ORDER )
225
226Fetches the $ORDER’s certificate chain and returns
227it in the format implied by the
228`application/pem-certificate-chain` MIME type. See the ACME
229protocol specification for details about this format.
230
231# TODO
232
233- Add pre-authorization support if there is ever a production
234use for it.
235- Expose the Retry-After header via the module API.
236- There is currently no way to fetch an order or challenge’s
237properties via URL. Prior to ACME’s adoption of “POST-as-GET” this was
238doable via a plain GET to the URL, but that’s no longer possible.
239If there’s a need, I’ll consider adding such logic to Net::ACME2.
240(It’s trivial to add; I’d just like to keep things as
241simple as possible.)
242- Add (more) tests.
243
244# SEE ALSO
245
246[Crypt::LE](https://metacpan.org/pod/Crypt::LE) is another ACME client library.
247
248[Crypt::Perl](https://metacpan.org/pod/Crypt::Perl) provides this library’s default cryptography backend.
249See this distribution’s `/examples` directory for sample usage
250to generate keys and CSRs.
251
252[Net::ACME](https://metacpan.org/pod/Net::ACME) implements client logic for the variant of this
253protocol that Let’s Encrypt first deployed.
254

eval_bug.readme

1#This bug was fixed in 5.12. Since 5.12 was out of support before this
2#module came into existence, there’s no point in filing an RT case for it.
3sub bug_exists {
4    local $@;
5    eval {
6        local $@;
7        die 123;
8    };
9    return $@ ? 0 : 1;
10}
11