Migrate docs to mkdocs

feature/mock
Richard Körber 2019-12-07 14:21:12 +01:00
parent 8c67344901
commit 925a116a38
No known key found for this signature in database
GPG Key ID: AAB9FD19C78AA3E0
43 changed files with 309 additions and 608 deletions

View File

@ -19,4 +19,4 @@ deploy:
- maven - maven
- docker - docker
script: script:
- mvn -B install site:site - mvn -B install javadoc:javadoc mkdocs:build

View File

@ -1,26 +0,0 @@
acme4j Client
=============
This is the main part of _acme4j_.
How to Use
----------
_acme4j_ is availabe at Maven Central. Just add this snippet to your `pom.xml`:
```xml
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
</dependency>
```
Java Module
-----------
Add this line to your module descriptor:
```java
requires org.shredzone.acme4j;
```

View File

@ -1,47 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
*
* acme4j - ACME Java client
*
* Copyright (C) 2015 Richard "Shred" Körber
* http://acme4j.shredzone.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
-->
<project xmlns="http://maven.apache.org/DECORATION/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/DECORATION/1.0.0 http://maven.apache.org/xsd/decoration-1.0.0.xsd">
<publishDate position="right"/>
<version position="right"/>
<body>
<head>
<!-- Workaround for https://issues.apache.org/jira/browse/DOXIA-571 -->
<![CDATA[<script type="text/javascript">$(document).ready(function(){$(".source").addClass("prettyprint");prettyPrint();});</script>]]>
</head>
<links>
<item name="API javadoc" href="./apidocs/index.html"/>
<item name="GitHub" href="https://github.com/shred/acme4j"/>
</links>
<breadcrumbs>
<item name="shredzone.org" href="https://shredzone.org"/>
<item name="acme4j" href="../index.html"/>
<item name="acme4j-client" href="index.html"/>
</breadcrumbs>
<menu name="Main">
<item name="Description" href="index.html"/>
</menu>
<menu ref="modules"/>
<menu ref="reports"/>
</body>
<skin>
<groupId>org.apache.maven.skins</groupId>
<artifactId>maven-fluido-skin</artifactId>
<version>1.7</version>
</skin>
</project>

View File

@ -1,19 +0,0 @@
acme4j Example
==============
An example tool that uses _acme4j_, and a good starting point to find out how _acme4j_ is used.
This tool registers a new account with the _Let's Encrypt_ staging server, and fetches a certificate for a set of domains.
How to Use
----------
Run the `org.shredzone.acme4j.ClientTest` class with the domains to be registered as parameters.
You can also invoke the example tool via maven:
```
mvn exec:java -Dexec.args="example.com example.org"
```
Or just have a look at [the source code](./apidocs/src-html/org/shredzone/acme4j/ClientTest.html).

View File

@ -1,46 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
*
* acme4j - ACME Java client
*
* Copyright (C) 2015 Richard "Shred" Körber
* http://acme4j.shredzone.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
-->
<project xmlns="http://maven.apache.org/DECORATION/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/DECORATION/1.0.0 http://maven.apache.org/xsd/decoration-1.0.0.xsd">
<publishDate position="right"/>
<version position="right"/>
<body>
<head>
<!-- Workaround for https://issues.apache.org/jira/browse/DOXIA-571 -->
<![CDATA[<script type="text/javascript">$(document).ready(function(){$(".source").addClass("prettyprint");prettyPrint();});</script>]]>
</head>
<links>
<item name="GitHub" href="https://github.com/shred/acme4j"/>
</links>
<breadcrumbs>
<item name="shredzone.org" href="https://shredzone.org"/>
<item name="acme4j" href="../index.html"/>
<item name="acme4j-example" href="index.html"/>
</breadcrumbs>
<menu name="Main">
<item name="Description" href="index.html"/>
</menu>
<menu ref="modules"/>
<menu ref="reports"/>
</body>
<skin>
<groupId>org.apache.maven.skins</groupId>
<artifactId>maven-fluido-skin</artifactId>
<version>1.7</version>
</skin>
</project>

View File

@ -1,17 +0,0 @@
acme4j Integration Tests
========================
This module contains an Integration Test of _acme4j_.
It builds a [Pebble](https://github.com/letsencrypt/pebble) docker image and runs it. After that, a number of integration tests are performed.
See the [Documentation](../development/testing.html) for how to run it
GitLab CI
---------
_acme4j_ contains a GitLab CI configuration file.
The CI runner should be set up with a `shell` executor. Maven and Docker should be installed on the CI runner, and the shell executor user should be able to use both.
The tags `maven` and `docker` are used to select the executor.

View File

@ -1,46 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
*
* acme4j - ACME Java client
*
* Copyright (C) 2017 Richard "Shred" Körber
* http://acme4j.shredzone.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
-->
<project xmlns="http://maven.apache.org/DECORATION/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/DECORATION/1.0.0 http://maven.apache.org/xsd/decoration-1.0.0.xsd">
<publishDate position="right"/>
<version position="right"/>
<body>
<head>
<!-- Workaround for https://issues.apache.org/jira/browse/DOXIA-571 -->
<![CDATA[<script type="text/javascript">$(document).ready(function(){$(".source").addClass("prettyprint");prettyPrint();});</script>]]>
</head>
<links>
<item name="GitHub" href="https://github.com/shred/acme4j"/>
</links>
<breadcrumbs>
<item name="shredzone.org" href="https://shredzone.org"/>
<item name="acme4j" href="../index.html"/>
<item name="acme4j-it" href="index.html"/>
</breadcrumbs>
<menu name="Main">
<item name="Description" href="index.html"/>
</menu>
<menu ref="modules"/>
<menu ref="reports"/>
</body>
<skin>
<groupId>org.apache.maven.skins</groupId>
<artifactId>maven-fluido-skin</artifactId>
<version>1.7</version>
</skin>
</project>

View File

@ -1,28 +0,0 @@
acme4j Utils
============
Some utility classes to be used with _acme4j_. They will help generating and processing keys and signatures.
Note that (unlike `acme4j-client`) this module requires [Bouncy Castle](https://www.bouncycastle.org/java.html).
How to Use
----------
Just add this snippet to your `pom.xml`:
```xml
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
</dependency>
```
Java Module
-----------
Add this line to your module descriptor:
```java
requires org.shredzone.acme4j.utils;
```

View File

@ -1,47 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
*
* acme4j - ACME Java client
*
* Copyright (C) 2015 Richard "Shred" Körber
* http://acme4j.shredzone.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
-->
<project xmlns="http://maven.apache.org/DECORATION/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/DECORATION/1.0.0 http://maven.apache.org/xsd/decoration-1.0.0.xsd">
<publishDate position="right"/>
<version position="right"/>
<body>
<head>
<!-- Workaround for https://issues.apache.org/jira/browse/DOXIA-571 -->
<![CDATA[<script type="text/javascript">$(document).ready(function(){$(".source").addClass("prettyprint");prettyPrint();});</script>]]>
</head>
<links>
<item name="API javadoc" href="./apidocs/index.html"/>
<item name="GitHub" href="https://github.com/shred/acme4j"/>
</links>
<breadcrumbs>
<item name="shredzone.org" href="https://shredzone.org"/>
<item name="acme4j" href="../index.html"/>
<item name="acme4j-utils" href="index.html"/>
</breadcrumbs>
<menu name="Main">
<item name="Description" href="index.html"/>
</menu>
<menu ref="modules"/>
<menu ref="reports"/>
</body>
<skin>
<groupId>org.apache.maven.skins</groupId>
<artifactId>maven-fluido-skin</artifactId>
<version>1.7</version>
</skin>
</project>

61
pom.xml
View File

@ -125,21 +125,6 @@
</excludes> </excludes>
</configuration> </configuration>
</plugin> </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.8.2</version>
<configuration>
<outputEncoding>UTF-8</outputEncoding>
</configuration>
<dependencies>
<dependency>
<groupId>org.apache.maven.doxia</groupId>
<artifactId>doxia-module-markdown</artifactId>
<version>1.8</version>
</dependency>
</dependencies>
</plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId> <artifactId>maven-release-plugin</artifactId>
@ -164,33 +149,6 @@
</execution> </execution>
</executions> </executions>
</plugin> </plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
<reportSets>
<reportSet>
<reports>
<report>summary</report>
<report>dependency-info</report>
<report>scm</report>
<report>issue-management</report>
<report>dependencies</report>
<report>team</report>
<report>licenses</report>
</reports>
</reportSet>
</reportSets>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-report-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId> <artifactId>maven-javadoc-plugin</artifactId>
@ -202,12 +160,15 @@
</configuration> </configuration>
</plugin> </plugin>
<plugin> <plugin>
<groupId>com.github.spotbugs</groupId> <groupId>org.shredzone.maven</groupId>
<artifactId>spotbugs-maven-plugin</artifactId> <artifactId>mkdocs-maven-plugin</artifactId>
<version>3.1.12.2</version> <version>1.0</version>
<configuration>
<outputDirectory>${project.build.directory}/site</outputDirectory>
</configuration>
</plugin> </plugin>
</plugins> </plugins>
</reporting> </build>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>com.google.code.findbugs</groupId> <groupId>com.google.code.findbugs</groupId>
@ -261,7 +222,7 @@
<activation> <activation>
<jdk>[9,10]</jdk> <jdk>[9,10]</jdk>
</activation> </activation>
<reporting> <build>
<plugins> <plugins>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
@ -271,14 +232,14 @@
</configuration> </configuration>
</plugin> </plugin>
</plugins> </plugins>
</reporting> </build>
</profile> </profile>
<profile> <profile>
<id>java-11</id> <id>java-11</id>
<activation> <activation>
<jdk>[11,)</jdk> <jdk>[11,)</jdk>
</activation> </activation>
<reporting> <build>
<plugins> <plugins>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
@ -288,7 +249,7 @@
</configuration> </configuration>
</plugin> </plugin>
</plugins> </plugins>
</reporting> </build>
</profile> </profile>
</profiles> </profiles>
</project> </project>

17
src/doc/docs/ca/index.md Normal file
View File

@ -0,0 +1,17 @@
# Certificate Authorities
_acme4j_ should support any CA that is providing an ACME server.
## Available Providers
The _acme4j_ package contains these providers:
* [Let's Encrypt](letsencrypt.md)
* [Pebble](pebble.md)
More CAs may be supported in future releases of _acme4j_.
Also, CAs can publish provider jar files that plug into _acme4j_ and offer extended support.
!!! note
You can always connect to any ACMEv2 compliant server, by passing the `URL` of its directory service to the `Session`.

View File

@ -5,10 +5,10 @@ With the `dns-01` challenge, you prove to the CA that you are able to control th
`Dns01Challenge` provides a digest string: `Dns01Challenge` provides a digest string:
```java ```java
Dns01Challenge challenge = auth.findChallenge(Dns01Challenge.TYPE); Dns01Challenge challenge = auth.findChallenge(Dns01Challenge.class);
String domain = auth.getIdentifier().getDomain();
String digest = challenge.getDigest(); String digest = challenge.getDigest();
String domain = auth.getIdentifier().getDomain();
``` ```
The CA expects a TXT record at `_acme-challenge.${domain}` with the `digest` string as value. The CA expects a TXT record at `_acme-challenge.${domain}` with the `digest` string as value.

View File

@ -5,11 +5,11 @@ With the `http-01` challenge, you prove to the CA that you are able to control t
`Http01Challenge` provides two strings: `Http01Challenge` provides two strings:
```java ```java
Http01Challenge challenge = auth.findChallenge(Http01Challenge.TYPE); Http01Challenge challenge = auth.findChallenge(Http01Challenge.class);
String domain = auth.getIdentifier().getDomain();
String token = challenge.getToken(); String token = challenge.getToken();
String content = challenge.getAuthorization(); String content = challenge.getAuthorization();
String domain = auth.getIdentifier().getDomain();
``` ```
`token` is the name of the file that will be requested by the CA server. It must contain the `content` string, without any leading or trailing white spaces or line breaks. The `Content-Type` header must be either `text/plain` or absent. `token` is the name of the file that will be requested by the CA server. It must contain the `content` string, without any leading or trailing white spaces or line breaks. The `Content-Type` header must be either `text/plain` or absent.
@ -22,6 +22,5 @@ http://${domain}/.well-known/acme-challenge/${token}
The challenge is completed when the CA was able to download that file and found `content` in it. The challenge is completed when the CA was able to download that file and found `content` in it.
<div class="alert alert-info" role="alert"> !!! note
The request is sent to port 80 only. If your domain has multiple IP addresses, the CA randomly selects one of them. There is no way to choose a different port or a fixed IP address. The request is sent to port 80 only, but redirects are followed. If your domain has multiple IP addresses, the CA randomly selects one of them. There is no way to choose a different port or a fixed IP address.
</div>

View File

@ -6,9 +6,9 @@ There are different kind of challenges. The most simple is maybe the HTTP challe
The ACME specifications define these standard challenges: The ACME specifications define these standard challenges:
* [http-01](./http-01.html) * [http-01](http-01.md)
* [dns-01](./dns-01.html) * [dns-01](dns-01.md)
_acme4j_ also supports these non-standard challenges: _acme4j_ also supports these non-standard challenges:
* [tls-alpn-01](./tls-alpn-01.html) * [tls-alpn-01](tls-alpn-01.md)

View File

@ -2,35 +2,32 @@
With the `tls-alpn-01` challenge, you prove to the CA that you are able to control the web server of the domain to be authorized, by letting it respond to a request with a specific self-signed cert utilizing the ALPN extension. With the `tls-alpn-01` challenge, you prove to the CA that you are able to control the web server of the domain to be authorized, by letting it respond to a request with a specific self-signed cert utilizing the ALPN extension.
<div class="alert alert-info" role="alert"> !!! note
This challenge is not part of the ACME specifications. It is specified [in a separate IETF document](https://tools.ietf.org/html/draft-ietf-acme-tls-alpn) and is still work in progress. This challenge is not part of the ACME specifications. It is specified [in a separate IETF document](https://tools.ietf.org/html/draft-ietf-acme-tls-alpn) and is still work in progress.
</div>
`TlsAlpn01Challenge` provides a byte array called `acmeValidation`: `TlsAlpn01Challenge` provides a byte array called `acmeValidation`:
```java ```java
TlsAlpn01Challenge challenge = auth.findChallenge(TlsAlpn01Challenge.TYPE); TlsAlpn01Challenge challenge = auth.findChallenge(TlsAlpn01Challenge.class);
Identifier identifier = auth.getIdentifier();
byte[] acmeValidation = challenge.getAcmeValidation(); byte[] acmeValidation = challenge.getAcmeValidation();
``` ```
You need to create a self-signed certificate with the domain to be validated set as the only _Subject Alternative Name_. The `acmeValidation` must be set as DER encoded `OCTET STRING` extension with the object id `1.3.6.1.5.5.7.1.31`. It is required to set this extension as critical. You need to create a self-signed certificate with the domain to be validated set as the only _Subject Alternative Name_. The `acmeValidation` must be set as DER encoded `OCTET STRING` extension with the object id `1.3.6.1.5.5.7.1.31`. It is required to set this extension as critical.
After that, configure your web server so it will use this certificate on an incoming TLS request having the SNI `subject` and the ALPN protocol `acme-tls/1`. After that, configure your web server so it will use this certificate on an incoming TLS request having the SNI `identifier` and the ALPN protocol `acme-tls/1`.
The `TlsAlpn01Challenge` class does not generate a self-signed certificate, as it would require _Bouncy Castle_. However, there is a utility method in the _acme4j-utils_ module for this use case: The `TlsAlpn01Challenge` class does not generate a self-signed certificate for you, as it would require _Bouncy Castle_. However, there is a utility method in the _acme4j-utils_ module for this use case:
```java ```java
Identifier identifier = auth.getIdentifier();
KeyPair certKeyPair = KeyPairUtils.createKeyPair(2048); KeyPair certKeyPair = KeyPairUtils.createKeyPair(2048);
X509Certificate cert = CertificateUtils. X509Certificate cert = CertificateUtils.
createTlsAlpn01Certificate(certKeyPair, identifier, acmeValidation); createTlsAlpn01Certificate(certKeyPair, identifier, acmeValidation);
``` ```
Now use `cert` and `certKeyPair` to let your web server respond to TLS requests containing an ALPN extension with the value `acme-tls/1` and a SNI extension containing your subject. Now use `cert` and `certKeyPair` to let your web server respond to TLS requests containing an ALPN extension with the value `acme-tls/1` and a SNI extension containing your subject (`identifier`).
<div class="alert alert-info" role="alert"> !!! note
The request is sent to port 443 only. If your domain has multiple IP addresses, the CA randomly selects one of them. There is no way to choose a different port or a fixed IP address. The request is sent to port 443 only. If your domain has multiple IP addresses, the CA randomly selects one of them. There is no way to choose a different port or a fixed IP address.
</div>

View File

@ -1,6 +1,6 @@
# _acme4j_ Development # acme4j Development
This part of the documentation is addressed to developers who want to extend _acme4j_, or who want to use _acme4j_ for integration tests. This part of the documentation is addressed to developers who want to extend _acme4j_, or who want to use _acme4j_ for integration tests.
* [Write an own Provider extension](./provider.html) * [Write an own Provider extension](provider.md)
* [Integration Tests](./testing.html) * [Integration Tests](testing.md)

View File

@ -1,4 +1,4 @@
# Testing _acme4j_ # Testing acme4j
## Integration Tests ## Integration Tests
@ -16,10 +16,8 @@ If you like to change the default configuration of the integration tests (e.g. b
* `pebblePort`: Port the pebble server is listening on. Default: 14000 * `pebblePort`: Port the pebble server is listening on. Default: 14000
* `bammbammUrl`: URI of the _pebble-challtestsrv_ to connect to. Default: `http://localhost:8055` * `bammbammUrl`: URI of the _pebble-challtestsrv_ to connect to. Default: `http://localhost:8055`
<div class="alert alert-danger" role="alert"> !!! warning
_pebble-challtestsrv_ is meant for testing purposes only. Only use it in secured testing environments. The server is neither hardened, nor does it offer any kind of authentication. _pebble-challtestsrv_ is meant for testing purposes only. Only use it in secured testing environments. The server is neither hardened, nor does it offer any kind of authentication.
</div>
## Boulder ## Boulder

71
src/doc/docs/index.md Normal file
View File

@ -0,0 +1,71 @@
# acme4j
A Java client for the _Automatic Certificate Management Environment_ (ACME) protocol as specified in [RFC 8555](https://tools.ietf.org/html/rfc8555).
ACME is a protocol that a certificate authority (CA) and an applicant can use to automate the process of verification and certificate issuance.
This Java client helps connecting to an ACME server, and performing all necessary steps to manage certificates.
It is an independent open source implementation that is not affiliated with or endorsed by _Let's Encrypt_.
The source code can be found at [GitHub](https://github.com/shred/acme4j) and is distributed under the terms of [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0).
Latest version: ![maven central](https://shredzone.org/maven-central/org.shredzone.acme4j/acme4j/badge.svg)
!!! danger
**Make sure to use _acme4j_ 2.5 or higher, before November 1st 2019.** Due to a change in the ACME protocol, _acme4j_ < 2.5 will fail to connect to servers after that date. See [here](https://community.letsencrypt.org/t/acme-v2-scheduled-deprecation-of-unauthenticated-resource-gets/74380) for details.
## Features
* Fully [RFC 8555](https://tools.ietf.org/html/rfc8555) compliant
* Supports the `http-01`, `dns-01` and `tls-alpn-01` challenges
* Supports the [acme-ip draft](https://tools.ietf.org/html/draft-ietf-acme-ip)
* Supports the [acme-star draft](https://tools.ietf.org/html/draft-ietf-acme-star) for short-term automatic certificate renewal (experimental)
* Easy to use Java API
* Requires JRE 8 (update 101) or higher
* Built with maven, packages available at [Maven Central](http://search.maven.org/#search|ga|1|g%3A%22org.shredzone.acme4j%22)
* Small, only requires [jose4j](https://bitbucket.org/b_c/jose4j/wiki/Home) and [slf4j](http://www.slf4j.org/) as dependencies
* Extensive unit and integration tests
## Quick Start
[This source code](acme4j-example/apidocs/src-html/org/shredzone/acme4j/ClientTest.html) gives an example of how to get a TLS certificate with _acme4j_.
You can run the `org.shredzone.acme4j.ClientTest` class in your IDE, with the domains to be registered as parameters. The test client can also be invoked via maven in a command line:
```sh
mvn exec:java -Dexec.args="example.com example.org"
```
By default, the test client registers the domains with the Let's Encrypt staging server via HTTP challenge.
## Modules
_acme4j_ consists of five modules. All modules are [available at Maven Central](https://mvnrepository.com/artifact/org.shredzone.acme4j) and can easily be added to the dependency list of your project. You can also download the jar files [at GitHub](https://github.com/shred/acme4j/releases/latest).
acme4j-client
: [`acme4j-client`](https://mvnrepository.com/artifact/org.shredzone.acme4j/acme4j-client/latest) is the main module. It contains everything that is required to get certificates for domains. It only requires [jose4j](https://bitbucket.org/b_c/jose4j) and [slf4j](https://www.slf4j.org/).
The Java module name is `org.shredzone.acme4j`.
acme4j-utils
: [`acme4j-utils`](https://mvnrepository.com/artifact/org.shredzone.acme4j/acme4j-utils/latest) contains utility classes for creating key pairs, CSRs, and certificates. It requires [Bouncy Castle](https://www.bouncycastle.org/java.html) though.
The Java module name is `org.shredzone.acme4j.utils`.
acme4j-example
: This module only contains [an example code](https://shredzone.org/maven/acme4j/acme4j-example/apidocs/src-html/org/shredzone/acme4j/ClientTest.html) that demonstrates how to get a certificate with _acme4j_. It is not useful as a dependency in other projects.
acme4j-it
: [`acme4j-it`](https://mvnrepository.com/artifact/org.shredzone.acme4j/acme4j-it/latest) mainly serves as integration test suite for _acme4j_ itself. It is not really useful as a dependency in other projects. However if you write own integration tests using [pebble](https://github.com/letsencrypt/pebble) and [pebble-challtestsrv](https://hub.docker.com/r/letsencrypt/pebble-challtestsrv), you may find the [`challtestsrv` configuration client](https://shredzone.org/maven/acme4j/acme4j-it/apidocs/org/shredzone/acme4j/it/BammBammClient.html) useful in your project.
The Java module name is `org.shredzone.acme4j.it`.
## Contribute
* Fork the [Source code at GitHub](https://github.com/shred/acme4j). Feel free to send pull requests.
* Found a bug? [File a bug report!](https://github.com/shred/acme4j/issues)
## License
_acme4j_ is open source software. The source code is distributed under the terms of [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0).

View File

@ -4,9 +4,8 @@ The first step is to register an account with the CA.
Your account needs a key pair. The public key is used to identify your account, while the private key is used to sign the requests to the ACME server. Your account needs a key pair. The public key is used to identify your account, while the private key is used to sign the requests to the ACME server.
<div class="alert alert-info" role="alert"> !!! note
Your private key is never transmitted to the ACME server. Your private key is never transmitted to the ACME server.
</div>
After the CA has created your account, it returns an account URL. You will need both the key pair and the account URL for logging into the account later. After the CA has created your account, it returns an account URL. You will need both the key pair and the account URL for logging into the account later.
@ -26,9 +25,8 @@ You can also create an elliptic curve key pair:
KeyPair accountKeyPair = KeyPairUtils.createECKeyPair("secp256r1"); KeyPair accountKeyPair = KeyPairUtils.createECKeyPair("secp256r1");
``` ```
<div class="alert alert-danger" role="alert"> !!! danger
Your key pair is the only way to access your account. If you should lose it, you will be locked out from your account and certificates. The API does not offer a way to recover access after a key loss. The only way is to contact the CA and ask for assistance. For this reason, it is strongly recommended to keep the key pair in a safe place! Your key pair is the only way to access your account. If you should lose it, you will be locked out from your account and certificates. The API does not offer a way to recover access after a key loss. The only way is to contact the CA and hope for assistance. For this reason, it is strongly recommended to keep the key pair in a safe place!
</div>
To save a `KeyPair` (actually, the private key of the key pair) to a pem file, you can use this snippet: To save a `KeyPair` (actually, the private key of the key pair) to a pem file, you can use this snippet:
@ -62,12 +60,10 @@ URL accountLocationUrl = account.getLocation();
If the account was successfully created, you will get an `Account` object in return. Invoking its `getLocation()` method will return the location URL of your account. Unlike your key pair, the location is a public information that does not need security precautions. If the account was successfully created, you will get an `Account` object in return. Invoking its `getLocation()` method will return the location URL of your account. Unlike your key pair, the location is a public information that does not need security precautions.
Now you have a key pair and the account's location URL. This is all you need for [logging in](./login.html). Now you have a key pair and the account's location URL. This is all you need for [logging in](login.md).
<div class="alert alert-info" role="alert">
!!! note
Even if it is tempting to do so, you should not invoke `agreeToTermsOfService()` automatically, but let the user confirm the terms of service first. To get a link to the current terms of service, you can invoke `session.getMetadata().getTermsOfService()`. Even if it is tempting to do so, you should not invoke `agreeToTermsOfService()` automatically, but let the user confirm the terms of service first. To get a link to the current terms of service, you can invoke `session.getMetadata().getTermsOfService()`.
</div>
If the CA changes the terms of service and requires an explicit agreement to the new terms, an `AcmeUserActionRequiredException` is thrown. Its `getInstance()` method returns the URL of a document that gives instructions about how to agree to the new terms of service. There is no way to automatize this process. If the CA changes the terms of service and requires an explicit agreement to the new terms, an `AcmeUserActionRequiredException` is thrown. Its `getInstance()` method returns the URL of a document that gives instructions about how to agree to the new terms of service. There is no way to automatize this process.
@ -128,10 +124,8 @@ account.deactivate();
Depending on the CA, the related authorizations may be automatically deactivated as well. The certificates may still be valid until expiration or explicit revocation. If you want to make sure the certificates are invalidated as well, revoke them prior to deactivation of your account. Depending on the CA, the related authorizations may be automatically deactivated as well. The certificates may still be valid until expiration or explicit revocation. If you want to make sure the certificates are invalidated as well, revoke them prior to deactivation of your account.
<div class="alert alert-danger" role="alert"> !!! danger
There is no way to reactivate the account once it is deactivated! There is no way to reactivate the account once it is deactivated!
</div>
## Custom Key Identifier ## Custom Key Identifier

View File

@ -17,10 +17,8 @@ This is a very simple example. You should limit the number of loop iterations, a
`update()` may throw an `AcmeRetryAfterException`, giving an estimated instant in `getRetryAfter()` when the certificate is available. You should then wait until that moment has been reached, before trying again. The state of your `Order` instance is still updated when this exception is thrown. `update()` may throw an `AcmeRetryAfterException`, giving an estimated instant in `getRetryAfter()` when the certificate is available. You should then wait until that moment has been reached, before trying again. The state of your `Order` instance is still updated when this exception is thrown.
<div class="alert alert-info" role="alert"> !!! tip
If the status is `PENDING`, you have not completed all authorizations yet. If the status is `PENDING`, you have not completed all authorizations yet.
</div>
As soon as the status is `VALID`, you can retrieve a `Certificate` object: As soon as the status is `VALID`, you can retrieve a `Certificate` object:
@ -53,12 +51,10 @@ try (FileWriter fw = new FileWriter("cert-chain.crt")) {
Certificates are only valid for a limited time, and need to be renewed before expiry. Certificates are only valid for a limited time, and need to be renewed before expiry.
<div class="alert alert-info" role="alert"> !!! tip
You can find out the expiry date of a `X509Certificate` by invoking its `getNotAfter()` method. You can find out the expiry date of a `X509Certificate` by invoking its `getNotAfter()` method.
</div>
A certificate can be renewed a few days before its expiry. There is no explicit method for certificate renewal. To renew it, just [order](./order.html) the certificate again. A certificate can be renewed a few days before its expiry. There is no explicit method for certificate renewal. To renew it, just [order](order.md) the certificate again.
## Revocation ## Revocation
@ -94,6 +90,5 @@ X509Certificate cert = ... // certificate to revoke
Certificate.revoke(session, domainKeyPair, cert, RevocationReason.KEY_COMPROMISE); Certificate.revoke(session, domainKeyPair, cert, RevocationReason.KEY_COMPROMISE);
``` ```
<div class="alert alert-danger" role="alert"> !!! warning
There is no way to revoke a certificate if you have lost both your account's key pair and your domain's key pair. There is no way to revoke a certificate if you have lost both your account's key pair and your domain's key pair.
</div>

View File

@ -0,0 +1,11 @@
# How to Use acme4j
_acme4j_ is a client library that helps connecting to ACME servers without worrying about specification details.
To get a certificate from your ACME CA, these steps need to be performed:
* [Start a Session](session.md)
* [Register a new Account](account.md)
* [Login into an Account](login.md)
* [Order a Certificate](order.md)
* [Download a Certificate](certificate.md)

View File

@ -21,10 +21,8 @@ Now you can simply get your `Account` instance from the `Login`:
Account account = login.getAccount(); Account account = login.getAccount();
``` ```
<div class="alert alert-info" role="alert"> !!! tip
It is possible to have multiple `Login`s to different accounts per session. This is useful if your software handles the certificates of more than one account. It is possible to have multiple `Login`s to different accounts per session. This is useful if your software handles the certificates of more than one account.
</div>
## Login on Creation ## Login on Creation
@ -63,14 +61,9 @@ However the `Login` the object is bound with is _not_ serialized! The reason is
This means that a deserialized object is not bound to a `Login` yet. It is required to rebind it to a `Login`, by invoking the `rebind()` method of the resource object. This means that a deserialized object is not bound to a `Login` yet. It is required to rebind it to a `Login`, by invoking the `rebind()` method of the resource object.
<div class="alert alert-info" role="alert"> !!! note
Serialization is only meant for short term storage at runtime, not for long term persistence. Serialization is only meant for short term storage at runtime, not for long term persistence.
For long term persistence, store the location URL of the resource, then bind it at later time like mentioned above. For long term persistence, store the location URL of the resource, then bind it at later time like mentioned above.
</div>
<div class="alert alert-info" role="alert">
!!! warning
Do not share serialized data between different versions of _acme4j_. Do not share serialized data between different versions of _acme4j_.
</div>

View File

@ -13,9 +13,8 @@ Order order = account.newOrder()
.create(); .create();
``` ```
<div class="alert alert-info" role="alert"> !!! note
The number of domains per certificate may be limited. See your CA's documentation for the limits. The number of domains per certificate may be limited. See your CA's documentation for the limits.
</div>
The `Order` resource contains a collection of `Authorization`s that can be read from the `getAuthorizations()` method. You must process _all of them_ in order to get the certificate, except those with a `VALID` status. The `Order` resource contains a collection of `Authorization`s that can be read from the `getAuthorizations()` method. You must process _all of them_ in order to get the certificate, except those with a `VALID` status.
@ -29,7 +28,7 @@ for (Authorization auth : order.getAuthorizations()) {
## Process an Authorization ## Process an Authorization
The `Authorization` instance contains further details about how you can prove ownership of your domain. An ACME server offers combinations of different authorization methods, called `Challenge`s. The `Authorization` instance contains further details about how you can prove ownership of your domain. An ACME server offers one or more authorization methods, called `Challenge`s.
`getChallenges()` returns a collection of all `Challenge`s offered by the CA for domain ownership validation. You only need to complete _one_ of them to successfully authorize your domain. `getChallenges()` returns a collection of all `Challenge`s offered by the CA for domain ownership validation. You only need to complete _one_ of them to successfully authorize your domain.
@ -40,9 +39,12 @@ Http01Challenge challenge = auth.findChallenge(Http01Challenge.TYPE); // by name
Http01Challenge challenge = auth.findChallenge(Http01Challenge.class); // by type Http01Challenge challenge = auth.findChallenge(Http01Challenge.class); // by type
``` ```
It returns a properly casted `Challenge` object, or `null` if your challenge type was not acceptable. In this example, your system is able to respond to a [http-01](../challenge/http-01.html) challenge. It returns a properly casted `Challenge` object, or `null` if your challenge type was not acceptable. In this example, your system is able to respond to a [http-01](../challenge/http-01.md) challenge.
The returned `Challenge` resource provides all the data that is necessary for a successful verification of your domain ownership. Your response depends on the challenge type (see the [documentation of challenges](../challenge/index.html)). !!! tip
Passing the challenge class is preferred over the challenge name, as type checks are performed at compile time here. Passing in the challenge name might result in a `ClassCastException` at runtime.
The returned `Challenge` resource provides all the data that is necessary for a successful verification of your domain ownership. Your response depends on the challenge type (see the [documentation of challenges](../challenge/index.md)).
After you have performed the necessary steps to set up the response to the challenge (e.g. configuring your web server or modifying your DNS records), the ACME server is told to test your response: After you have performed the necessary steps to set up the response to the challenge (e.g. configuring your web server or modifying your DNS records), the ACME server is told to test your response:
@ -75,9 +77,8 @@ After successfully completing all authorizations, the order needs to be finalize
CSR files can be generated with command line tools like `openssl`. Unfortunately the standard Java does not offer classes for that, so you'd have to resort to [Bouncy Castle](http://www.bouncycastle.org/java.html) if you want to create a CSR programmatically. In the `acme4j-utils` module, there is a [`CSRBuilder`](../apidocs/org/shredzone/acme4j/util/CSRBuilder.html) for your convenience. You can also use [`KeyPairUtils`](../apidocs/org/shredzone/acme4j/util/KeyPairUtils.html) for generating a new key pair for your domain. CSR files can be generated with command line tools like `openssl`. Unfortunately the standard Java does not offer classes for that, so you'd have to resort to [Bouncy Castle](http://www.bouncycastle.org/java.html) if you want to create a CSR programmatically. In the `acme4j-utils` module, there is a [`CSRBuilder`](../apidocs/org/shredzone/acme4j/util/CSRBuilder.html) for your convenience. You can also use [`KeyPairUtils`](../apidocs/org/shredzone/acme4j/util/KeyPairUtils.html) for generating a new key pair for your domain.
<div class="alert alert-info" role="alert"> !!! tip
Do not just use your account key pair as domain key pair, but always generate separate key pairs! Never use your account key pair as domain key pair, but always generate separate key pairs!
</div>
```java ```java
KeyPair domainKeyPair = ... // KeyPair to be used for HTTPS encryption KeyPair domainKeyPair = ... // KeyPair to be used for HTTPS encryption
@ -107,10 +108,8 @@ order.execute(csr);
You can also generate a wildcard certificate that is valid for all subdomains of a domain, by prefixing the domain name with `*.` (e.g. `*.example.org`). The domain itself is not covered by the wildcard certificate, and also needs to be added to the order if necessary. You can also generate a wildcard certificate that is valid for all subdomains of a domain, by prefixing the domain name with `*.` (e.g. `*.example.org`). The domain itself is not covered by the wildcard certificate, and also needs to be added to the order if necessary.
<div class="alert alert-info" role="alert"> !!! note
_acme4j_ accepts all kind of wildcard notations (e.g. `www.*.example.org`, `*.*.example.org`). However, those notations are not specified and may be rejected by your CA. _acme4j_ accepts all kind of wildcard notations (e.g. `www.*.example.org`, `*.*.example.org`). However, those notations are not specified and may be rejected by your CA.
</div>
You must be able to prove ownership of the domain that you want to order a wildcard certificate for. The corresponding `Authorization` resource only refers to that domain, and does not contain the wildcard notation. You must be able to prove ownership of the domain that you want to order a wildcard certificate for. The corresponding `Authorization` resource only refers to that domain, and does not contain the wildcard notation.
@ -134,10 +133,8 @@ order.execute(csr);
In the subsequent authorization process, you would have to prove ownership of the `example.org` domain. In the subsequent authorization process, you would have to prove ownership of the `example.org` domain.
<div class="alert alert-info" role="alert"> !!! note
Some CAs may reject wildcard certificate orders, may only offer a limited set of `Challenge`s, or may involve `Challenge`s that are not documented here. Refer to your CA's documentation to find out about the wildcard certificate policy. Some CAs may reject wildcard certificate orders, may only offer a limited set of `Challenge`s, or may involve `Challenge`s that are not documented here. Refer to your CA's documentation to find out about the wildcard certificate policy.
</div>
## Pre-Authorize a Domain ## Pre-Authorize a Domain
@ -150,15 +147,11 @@ String domain = ... // Domain name to authorize
Authorization auth = account.preAuthorizeDomain(domain); Authorization auth = account.preAuthorizeDomain(domain);
``` ```
<div class="alert alert-info" role="alert"> !!! note
Some CAs may not offer domain pre-authorization. `preAuthorizeDomain()` will then fail and throw an `AcmeException`. Some CAs may not offer domain pre-authorization. `preAuthorizeDomain()` will then fail and throw an `AcmeException`.
</div>
<div class="alert alert-info" role="alert">
!!! note
Some CAs may not offer wildcard domain pre-authorization, but only wildcard domain orders. Some CAs may not offer wildcard domain pre-authorization, but only wildcard domain orders.
</div>
## Deactivate an Authorization ## Deactivate an Authorization
@ -168,9 +161,8 @@ It is possible to deactivate an `Authorization`, for example if you sell the ass
auth.deactivate(); auth.deactivate();
``` ```
<div class="alert alert-info" role="alert"> !!! tip
It is not documented if the deactivation of an authorization also revokes the related certificate. If the certificate should be revoked, revoke it manually before deactivation. It is not documented if the deactivation of an authorization also revokes the related certificate. If the certificate should be revoked, revoke it manually before deactivation.
</div>
## Use IP Identifiers ## Use IP Identifiers
@ -200,10 +192,8 @@ byte[] csr = csrb.getEncoded();
_acme4j_ supports the [ACME STAR](https://tools.ietf.org/html/draft-ietf-acme-star) extension for short-term automatic renewal of certificates. _acme4j_ supports the [ACME STAR](https://tools.ietf.org/html/draft-ietf-acme-star) extension for short-term automatic renewal of certificates.
<div class="alert alert-warning" role="alert"> !!! warning
The _ACME STAR_ support is experimental. There is currently no known ACME server implementing this extension. The _ACME STAR_ support is experimental. There is currently no known ACME server implementing this extension.
</div>
To find out if the CA supports the STAR extension, check the metadata: To find out if the CA supports the STAR extension, check the metadata:
@ -230,9 +220,8 @@ After the validation process is completed and the order is finalized, the STAR c
Use `Certificate.getLocation()` to retrieve the URL of your certificate. It is renewed automatically, so you will always be able to download the latest issue of the certificate from this URL. Use `Certificate.getLocation()` to retrieve the URL of your certificate. It is renewed automatically, so you will always be able to download the latest issue of the certificate from this URL.
<div class="alert alert-info" role="alert"> !!! note
STAR based certificates cannot be revoked. However, as it is the nature of these certs to be short-lived, this does not pose an actual security issue. STAR based certificates cannot be revoked. However, as it is the nature of these certs to be short-lived, this does not pose an actual security issue.
</div>
To download the latest certificate issue, you can bind the certificate URL to your `Login` and then use the `Certificate` object. To download the latest certificate issue, you can bind the certificate URL to your `Login` and then use the `Certificate` object.

44
src/doc/mkdocs.yml Normal file
View File

@ -0,0 +1,44 @@
site_name: acme4j
site_author: Richard Körber
site_url: https://acme4j.shredzone.org
site_dir: target/site/
repo_url: https://github.com/shred/acme4j
edit_uri: ''
use_directory_urls: false
theme:
name: readthedocs
custom_dir: theme/
highlightjs: false
markdown_extensions:
- admonition
- codehilite
- def_list
- toc:
permalink: true
nav:
- 'index.md'
- JavaDocs:
- 'acme4j-client': acme4j-client/apidocs/index.html
- 'acme4j-utils': acme4j-utils/apidocs/index.html
- 'acme4j-it': acme4j-it/apidocs/index.html
- Usage:
- 'usage/index.md'
- 'usage/session.md'
- 'usage/account.md'
- 'usage/login.md'
- 'usage/order.md'
- 'usage/certificate.md'
- Challenges:
- 'challenge/index.md'
- 'challenge/http-01.md'
- 'challenge/dns-01.md'
- 'challenge/tls-alpn-01.md'
- CA:
- 'ca/index.md'
- 'ca/letsencrypt.md'
- 'ca/pebble.md'
- Development:
- 'development/index.md'
- 'development/provider.md'
- 'development/testing.md'
- 'migration.md'

0
src/doc/theme/breadcrumbs.html vendored Normal file
View File

35
src/doc/theme/css/font.css vendored Normal file
View File

@ -0,0 +1,35 @@
/*
* Lato
* Copyright 2010-2011 tyPoland Lukasz Dziedzic
* SIL Open Font License, 1.1
*/
@font-face {
font-family: 'Lato';
font-style: normal;
font-weight: 400;
src: local('Lato Regular'), local('Lato-Regular'), url('../fonts/lato-v15-latin-regular.woff') format('woff');
}
/*
* Roboto Slab
* Copyright 2013 Google
* Apache License, version 2.0
*/
@font-face {
font-family: 'Roboto Slab';
font-style: normal;
font-weight: 400;
src: local('Roboto Slab Regular'), local('RobotoSlab-Regular'), url('../fonts/roboto-slab-v8-latin-regular.woff') format('woff');
}
/*
* Inconsolata
* Copyright 2006 The Inconsolata Project Authors
* SIL Open Font License, 1.1
*/
@font-face {
font-family: 'Inconsolata';
font-style: normal;
font-weight: 400;
src: local('Inconsolata Regular'), local('Inconsolata-Regular'), url('../fonts/inconsolata-v17-latin-regular.woff') format('woff');
}

14
src/doc/theme/css/theme_custom.css vendored Normal file
View File

@ -0,0 +1,14 @@
.wy-nav-content {
max-width: none;
}
pre {
background-color: #f6f6f6;
padding: .4rem;
overflow-x: auto;
}
footer {
margin-top: 2rem;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

10
src/doc/theme/footer.html vendored Normal file
View File

@ -0,0 +1,10 @@
<footer>
<div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
{% if page.next_page %}
<a href="{{ page.next_page.url|url }}" class="btn btn-neutral float-right" title="{{ page.next_page.title }}">Next <span class="icon icon-circle-arrow-right"></span></a>
{% endif %}
{% if page.previous_page %}
<a href="{{ page.previous_page.url|url }}" class="btn btn-neutral" title="{{ page.previous_page.title }}"><span class="icon icon-circle-arrow-left"></span> Previous</a>
{% endif %}
</div>
</footer>

15
src/doc/theme/main.html vendored Normal file
View File

@ -0,0 +1,15 @@
{% extends "base.html" %}
{% block styles %}
<link rel="stylesheet" href="{{ 'css/font.css'|url }}" />
<link rel="stylesheet" href="{{ 'css/theme.css'|url }}" />
<link rel="stylesheet" href="{{ 'css/theme_extra.css'|url }}" />
<link rel="stylesheet" href="{{ 'css/theme_custom.css'|url }}" />
{%- for path in config['extra_css'] %}
<link href="{{ path|url }}" rel="stylesheet" />
{%- endfor %}
{% endblock %}
{% block repo %}
<a href="https://shredzone.org/maven/acme4j/apidocs/index.html">API javadoc</a>s
{% endblock %}

9
src/doc/theme/toc.html vendored Normal file
View File

@ -0,0 +1,9 @@
{% for toc_item in page.toc %}
{% if toc_item.children %}
<ul>
{% for toc_item in toc_item.children %}
<li><a class="toctree-l{{ navlevel + 2 }}" href="{{ toc_item.url }}">{{ toc_item.title }}</a></li>
{% endfor %}
</ul>
{% endif %}
{% endfor %}

View File

@ -1,19 +0,0 @@
# Certificate Authorities
_acme4j_ should support any CA providing an ACME server.
## Available Providers
The _acme4j_ package contains these providers:
* [Let's Encrypt](./letsencrypt.html)
* [Pebble](./pebble.html)
More CAs may be supported in future releases of _acme4j_.
Also, CAs can publish provider jar files that plug into _acme4j_ and offer extended support.
<div class="alert alert-info" role="alert">
You can always connect to any ACMEv2 compliant server, by passing the `URL` of its directory service to the `Session`.
</div>

View File

@ -1,58 +0,0 @@
acme4j
======
A Java client for the _Automatic Certificate Management Environment_ (ACME) protocol as specified in [RFC 8555](https://tools.ietf.org/html/rfc8555).
ACME is a protocol that a certificate authority (CA) and an applicant can use to automate the process of verification and certificate issuance.
This Java client helps connecting to an ACME server, and performing all necessary steps to manage certificates.
It is an independent open source implementation that is not affiliated with or endorsed by _Let's Encrypt_.
The source code can be found at [GitHub](https://github.com/shred/acme4j) and is distributed under the terms of [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0).
<div class="alert alert-info" role="alert">
**Note:** Make sure to use _acme4j_ 2.5 or higher, before November 1st 2019. Due to a change in the ACME protocol, _acme4j_ < 2.5 will fail to connect to servers after that date. _acme4j_ v1 is not affected. See [here](https://community.letsencrypt.org/t/acme-v2-scheduled-deprecation-of-unauthenticated-resource-gets/74380) for details.
</div>
Quick Start
-----------
_acme4j_ is available at Maven Central. Just add this snippet to your `pom.xml`:
```xml
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}-client</artifactId>
<version>${project.version}</version>
</dependency>
```
For Gradle:
```groovy
dependencies {
compile '${project.groupId}:${project.artifactId}-client:${project.version}'
}
```
There is also an optional utility module that will help you handling key pairs and certificates (but requires [Bouncy Castle](https://www.bouncycastle.org/java.html)):
```xml
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}-utils</artifactId>
<version>${project.version}</version>
</dependency>
```
For Gradle:
```groovy
dependencies {
compile '${project.groupId}:${project.artifactId}-utils:${project.version}'
}
```
Now just have a look at [this source code](./acme4j-example/apidocs/src-html/org/shredzone/acme4j/ClientTest.html) to see an example usage.

View File

@ -1,11 +0,0 @@
# How to Use _acme4j_
_acme4j_ is a client library that helps connecting to ACME servers without worrying about specification details.
To get a certificate from your ACME CA, these steps need to be performed:
* [Start a Session](./session.html)
* [Register a new Account](./account.html)
* [Login into an Account](./login.html)
* [Order a Certificate](./order.html)
* [Download a Certificate](./certificate.html)

View File

@ -1,20 +0,0 @@
.alert {
border: none;
padding: 5px 10px;
}
.alert-info {
border-left: 10px solid #3a87ad;
}
.alert-warning {
border-left: 10px solid #c09853;
}
.alert-danger {
border-left: 10px solid #b94a48;
}
.alert p {
margin: 0;
}

View File

@ -1,67 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
*
* acme4j - ACME Java client
*
* Copyright (C) 2015 Richard "Shred" Körber
* http://acme4j.shredzone.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
-->
<project xmlns="http://maven.apache.org/DECORATION/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/DECORATION/1.0.0 http://maven.apache.org/xsd/decoration-1.0.0.xsd">
<publishDate position="right"/>
<version position="right"/>
<body>
<head>
<!-- Workaround for https://issues.apache.org/jira/browse/DOXIA-571 -->
<![CDATA[<script type="text/javascript">$(document).ready(function(){$(".source").addClass("prettyprint");prettyPrint();});</script>]]>
</head>
<links>
<item name="API javadoc" href="./apidocs/index.html"/>
<item name="GitHub" href="https://github.com/shred/acme4j"/>
</links>
<breadcrumbs>
<item name="shredzone.org" href="https://shredzone.org"/>
<item name="acme4j" href="index.html"/>
</breadcrumbs>
<menu name="Documentation">
<item name="Introduction" href="index.html"/>
<item name="Migration Guide" href="migration.html"/>
<item name="How to Use" href="usage/index.html">
<item name="Session" href="usage/session.html"/>
<item name="Account" href="usage/account.html"/>
<item name="Login" href="usage/login.html"/>
<item name="Order and Authorization" href="usage/order.html"/>
<item name="Certificate" href="usage/certificate.html"/>
</item>
<item name="Challenges" href="challenge/index.html">
<item name="http-01" href="challenge/http-01.html"/>
<item name="dns-01" href="challenge/dns-01.html"/>
<item name="tls-alpn-01" href="challenge/tls-alpn-01.html"/>
</item>
<item name="CAs" href="ca/index.html">
<item name="Let's Encrypt" href="ca/letsencrypt.html"/>
<item name="Pebble" href="ca/pebble.html"/>
</item>
<item name="Development" href="development/index.html">
<item name="ACME Provider" href="development/provider.html"/>
<item name="Testing" href="development/testing.html"/>
</item>
</menu>
<menu ref="modules"/>
<menu ref="reports"/>
</body>
<skin>
<groupId>org.apache.maven.skins</groupId>
<artifactId>maven-fluido-skin</artifactId>
<version>1.7</version>
</skin>
</project>