ssl.com requires EAB for account creation, but the metadata's
"externalAccountRequired" property gives "false", indicating that no EAB
is used.
This fix patches the read directory's metadata if the ssl.com provider
is used.
These are genuine functionality changes, and may represent unexpected
impact. Having two CNs doesn't seem right, but that case is tested so
I'm leaving that here for discussion's sake.
The other test case doesn't have a CN anymore, as expected
Required by Java as well as the Baseline Requirements, RFC5280, etc.
If the subject field of the certificate is an empty SEQUENCE, this
extension MUST be marked critical, as specified in RFC 5280, Section
4.2.1.6. Otherwise, this extension MUST NOT be marked critical.
With this change, it is not stricly required anymore to create the CSR
oneself. The Order class contains all information to generate a basic
CSR itself.
The separation of acme4j-client and acme4j-utils was a design decision
that should avoid BouncyCastle to be a hard dependency of acme4j-client.
Anyhow acme4j is not really usable without BouncyCastle, so acme4j-utils
is used in almost all projects anyway.
This merge allows to extend the client API with some nice methods that
will make it easier to use.
Before this patch, Order generated and bound new Authorization and
Certificate objects everytime the respective getters were invoked. Each
of these instances keeps a separate copy of the server state, which causes
unnecessary traffic.
With this patch, the list of Authorizations and the Certificates are now
loaded lazily and kept in a cache, so the same instance is returned
everytime the getter is invoked.
Similar to getCertificate(), getAutoRenewalCertificate() would only
return an empty optional if the order state is not valid. To keep the
API simple, getAutoRenewalCertificate() now always returns a non-null
certificate, and throws an exception otherwise.
While reviewing the code, it turned out that the invoker of
getLocation() always expected to find a location header. To keep the API
simple, getLocation() now always returns the non-null Location header.
If the header is not present, an AcmeProtocolException is now thrown
instead.
- Some Optional return values could only be empty if a method was
invoked although the server did not support that feature. In order to
keep the API simple, a newly introduced AcmeNotSupportedException is
now thrown in that case, so these methods will immediately return a
non-null value. There is always a method to check if a feature is
available or not, so the invoker can check in advance and does not
need to actively handle that exception.
- Some other places that previously threw an exception because of
missing features, are now also throwing AcmeNotSupportedException for
consistency.
getCertificate() would only return Optional.empty() if it was invoked
before the order was finalized. In order to keep the API simple, that
state will now throw an IllegalStateException, and getCertificate()
directly returns a non-null Certificate now.
Before this patch, it was only the language tag of the selected Locale.
Now it also offers the language itself (without the country) and any
other available language as fallback. It is also possible to set the
locale to null, which will accept any language.
Works around a bug in Conscrypt. The certificate stream is not read
there if InputStream.available() returns 0, which is the case in acme4j
since the stream is directly read from the CA via HTTP.
The workaround uses a BufferedInputStream and prefetches a few bytes
from the HTTP stream if available() is invoked.
Until now, acme4j has cached the directory for 1 hour. This could lead to errors if the directory was changed, or the server was down for maintenance. Now acme4j caches the directory resource according to the HTTP Expires or Modified-Since headers.