Skip to content

Commit

Permalink
fix bugs about revoking certificates.
Browse files Browse the repository at this point in the history
  • Loading branch information
stonemax committed May 17, 2019
1 parent f3a0625 commit 9069758
Show file tree
Hide file tree
Showing 11 changed files with 266 additions and 38 deletions.
4 changes: 2 additions & 2 deletions README.md
Expand Up @@ -2,5 +2,5 @@
Another PHP client for acme protocal (version 2) implementation, used for generating letsencrypt's free ssl certificate.

## docs
* [English](https://github.com/stonemax/acme2/blob/develop/docs/README.md)
* [简体中文](https://github.com/stonemax/acme2/blob/develop/docs/README-ZH.md)
* [English](https://github.com/stonemax/acme2/blob/mster/docs/README.md)
* [简体中文](https://github.com/stonemax/acme2/blob/master/docs/README-ZH.md)
2 changes: 1 addition & 1 deletion VERSION
@@ -1 +1 @@
1.0.3
1.0.4
33 changes: 22 additions & 11 deletions docs/README-ZH.md
Expand Up @@ -3,7 +3,7 @@ stonemax/acme2 是一个简单的 PHP 工具,用于生成符合 ACME(Version 2


## 1. 当前版本
stonemax/acme2 当前的版本是 `1.0.0`
stonemax/acme2 当前的版本是 `1.0.4`


## 2. 先决条件
Expand All @@ -23,7 +23,7 @@ composer install


## 4. 使用
在这里,我们将介绍 stonemax/acme2 中对外暴露的方法,通过认识这些方法,您就大致知道如何使用了,我们也提供了一份案例代码,位于 [examples/](https://github.com/stonemax/acme2/tree/develop/examples) 目录下。
在这里,我们将介绍 stonemax/acme2 中对外暴露的方法,通过认识这些方法,您就大致知道如何使用了,我们也提供了一份案例代码,位于 [examples/](https://github.com/stonemax/acme2/tree/master/examples) 目录下。

#### 4.1. 初始化客户端

Expand All @@ -32,7 +32,6 @@ $emailList = ['alert@example.com']; // 邮箱列表,
$storagePath = './data'; // 账户数据以及生成的证书存储的目录
$staging = TRUE; // 是否使用 staging 环境


$client = new Client($emailList, $storagePath, $staging); // 初始化客户端
```

Expand Down Expand Up @@ -66,13 +65,21 @@ $domainInfo = [

$algorithm = CommonConstant::KEY_PAIR_TYPE_RSA; // 生成 RSA 类型的证书,使用 `CommonConstant::KEY_PAIR_TYPE_EC` 生成 ECDSA 证书

$order = $client->getOrder($domainInfo, $algorithm); // 获取订单实例
$order = $client->getOrder($domainInfo, $algorithm, TRUE); // 获取订单实例

$order->getPendingChallengeList(); // 获取 ChallengeService 实例列表,该列表中存储了域名验证的相关信息
$order->getCertificateFile(); // 获取证书的相关信息,包含:证书位置、生成证书的密钥对文件位置、证书有效期
$order->revokeCertificate($reason); // 吊销证书,证书吊销后就不能再使用了,需要重新生成
```

`getOrder()` 方法的原型为:

```php
public function getOrder(array $domainInfo,int $algorithm, bool $generateNewOder = TRUE): OrderService
```

其中第三个参数 `$generateNewOder` 控制是否创建新订单。当 `$generateNewOder == TRUE`,原证书目录下的所有文件均会被删除已用于生成新证书;当 `$generateNewOder == FALSE` 时,会返回一个已经存在的订单服务实例,一般用于撤销证书。

#### 4.4. 证书验证相关方法

```php
Expand All @@ -86,10 +93,10 @@ foreach ($challengeList as $challenge)
}
```

`verify` 方法的原型为:
`verify()` 方法的原型为:

```php
public function verify(int $verifyLocallyTimeout = 0, int $verifyCATimeout = 0) bool
public function verify(int $verifyLocallyTimeout = 0, int $verifyCATimeout = 0): bool
```

* 第一个参数 `$verifyLocallyTimeout` 为本地验证的超时时间。默认值 0 表明不会触发超时机制;
Expand Down Expand Up @@ -154,13 +161,17 @@ ACME2支持通配符证书的生成,但仅能使用 DNS 认证。拿 `*.www.ex
| \*.www.example.com | \_acme-challenge.www.example.com | TXT | 60 | eZ9ViY12gKfdruYHOO7Lu74ICXeQRMDLp5GuHLvPsf7 |


## 6. 完整例子
stonemax/acme2 随代码附上了一个完整的例子,位于 [examples/](https://github.com/stonemax/acme2/tree/develop/examples) 目录下,也可以点击 [examples/example.php](https://github.com/stonemax/acme2/blob/develop/examples/example.php) 直接查看。
## 6. 状态机
[各对象状态机](https://github.com/stonemax/acme2/blob/master/docs/state-machine-zh.md)


## 7. 完整例子
stonemax/acme2 随代码附上了一个完整的例子,位于 [examples/](https://github.com/stonemax/acme2/tree/master/examples) 目录下,也可以点击 [examples/example.php](https://github.com/stonemax/acme2/blob/master/examples/example.php) 直接查看。


## 7. 感谢
## 8. 感谢
[yourivw/LEClient](https://github.com/yourivw/LEClient) 项目对本项目有很大帮助,在此表示感谢!


## 8. 许可证
此项目使用的是 MIT 许可证,[查看许可证信息](https://github.com/stonemax/acme2/blob/develop/LICENSE)
## 9. 许可证
此项目使用的是 MIT 许可证,[查看许可证信息](https://github.com/stonemax/acme2/blob/master/LICENSE)
33 changes: 22 additions & 11 deletions docs/README.md
Expand Up @@ -4,7 +4,7 @@ stonemax/acme2 is a simple PHP tool to manage TLS certificates with ACME-complia


## 1. Current Version
The current version is `1.0.0`.
The current version is `1.0.4`.


## 2. Prerequisites
Expand All @@ -24,7 +24,7 @@ composer install


## 4. Usage
The basic methods and its necessary arguments are shown here. An example is supplied in [examples/](https://github.com/stonemax/acme2/tree/develop/examples).
The basic methods and its necessary arguments are shown here. An example is supplied in [examples/](https://github.com/stonemax/acme2/tree/master/examples).

#### 4.1. Client

Expand All @@ -33,7 +33,6 @@ $emailList = ['alert@example.com']; // Email list as co
$storagePath = './data'; // Account data and certificates files will be stored here
$staging = TRUE; // Using stage environment or not, make sure to empty $storagePath directory after you change from staging/test server to the real one


$client = new Client($emailList, $storagePath, $staging); // Initiating a client
```

Expand Down Expand Up @@ -68,13 +67,21 @@ $domainInfo = [

$algorithm = CommonConstant::KEY_PAIR_TYPE_RSA; // Generate RSA certificates, `CommonConstant::KEY_PAIR_TYPE_EC` for ECDSA certificates

$order = $client->getOrder($domainInfo, $algorithm); // Get an order service instance
$order = $client->getOrder($domainInfo, $algorithm, TRUE); // Get an order service instance

$order->getPendingChallengeList(); // Get all authorization challenges for domains
$order->getCertificateFile(); // Get certificates, such as certificates path, private/public key pair path, valid time
$order->revokeCertificate($reason); // Revoke certificates, the certificaes ara unavailable after revoked
```

The prototype of method `getOrder()` is shown as bellow:

```php
public function getOrder(array $domainInfo,int $algorithm, bool $generateNewOder = TRUE): OrderService
```

The third param `$generateNewOder` controls whether a new order need to be generated. When `$generateNewOder == TRUE`, all files under original certificates directory will be removed in order to generate new certificates; When `$generateNewOder == FALSE`, it will return an existing order service instance used to revoke certificates generally.

#### 4.4. Challenge

```php
Expand All @@ -88,10 +95,10 @@ foreach ($challengeList as $challenge)
}
```

The prototype of method `verify` is shown as bellow:
The prototype of method `verify()` is shown as bellow:

```php
public function verify(int $verifyLocallyTimeout = 0, int $verifyCATimeout = 0) bool
public function verify(int $verifyLocallyTimeout = 0, int $verifyCATimeout = 0): bool
```

* The first param `$verifyLocallyTimeout` stands for the timeout of local verification. Default value 0 won't trigger time-out mechanism;
Expand Down Expand Up @@ -161,13 +168,17 @@ Here is a simple summary for dns-01 challenges about domain and DNS record.
| \*.www.example.com | \_acme-challenge.www.example.com | TXT | 60 | eZ9ViY12gKfdruYHOO7Lu74ICXeQRMDLp5GuHLvPsf7 |


## 6. Full example
Project supplies a [full example](https://github.com/stonemax/acme2/blob/develop/examples/example.php) under directory [examples/](https://github.com/stonemax/acme2/tree/develop/examples).
## 6. State machine
[Objects's state machine](https://github.com/stonemax/acme2/blob/master/docs/state-machine-zh.md)


## 7. Full example
Project supplies a [full example](https://github.com/stonemax/acme2/blob/master/examples/example.php) under directory [examples/](https://github.com/stonemax/acme2/tree/master/examples).


## 7. Thanks
## 8. Thanks
This Project had got a lot of inspirations from [yourivw/LEClient](https://github.com/yourivw/LEClient). Thanks!


## 8. License
This project is licensed under the MIT License, see the [LICENSE](https://github.com/stonemax/acme2/blob/develop/LICENSE) file for detail.
## 9. License
This project is licensed under the MIT License, see the [LICENSE](https://github.com/stonemax/acme2/blob/master/LICENSE) file for detail.
94 changes: 94 additions & 0 deletions docs/state-machine-zh.md
@@ -0,0 +1,94 @@
## 1. 挑战 Challenge
挑战创建后进入 `pending` 状态。当客户端发起验证挑战请求后,进入 `processing` 状态,此时,服务器端开始验证客户端是否完成了挑战。值得注意的是,在 `processing` 阶段,服务器端可能会多次验证挑战是否完成。类似的,客户端请求重试验证不会造成状态改变。如果验证成功,挑战状态变更为 `valid`;如果发生错误,状态变更为 `invalid`

```text
pending
|
| Receive
| response
V
processing <-+
| | | Server retry or
| | | client retry request
| +----+
|
|
Successful | Failed
validation | validation
+---------+---------+
| |
V V
valid invalid
```


## 2. 授权 Authorization
授权创建后进入 `pending` 状态。如果授权的任意一个挑战转变为 `valid` 状态,授权也会进入 `valid` 状态。如果服务器端验证挑战失败,或者发生了错误(当授权状态仍为 `pending` 时),授权将进入 `invalid` 状态。一旦授权进入 `valid` 状态,授权可以过期 `expired`,可以被客户端停用 `deactivated`,可以被服务器端撤销 `revoked`

```text
pending --------------------+
| |
Challenge failure | |
or | |
Error | Challenge valid |
+---------+---------+ |
| | |
V V |
invalid valid |
| |
| |
| |
+--------------+--------------+
| | |
| | |
Server | Client | Time after |
revoke | deactivate | "expires" |
V V V
revoked deactivated expired
```


## 3. 订单 Order
订单创建后进入 `pending` 状态。只有当订单下的所有授权均进入 `valid` 状态,订单才会进入 `ready` 状态。当客户端调用了订单的 `finalize` URL,订单进入 `processing` 状态,此时服务器端开始签发证书。一旦证书签发完成,订单进入 `valid` 状态。如果在上述任一状态时发生错误,订单将进入 `invalid` 状态。如果订单过期了,或者任一授权的最终状态不是 `valid``expired``revoked`,或者 `deactivated`),订单也会进入 `invalid` 状态。

```text
pending --------------+
| |
| All authz |
| "valid" |
V |
ready ---------------+
| |
| Receive |
| finalize |
| request |
V |
processing ------------+
| |
| Certificate | Error or
| issued | Authorization failure
V V
valid invalid
```


## 4. 账户 Account
创建账户请求调用后,如果没有再进行后续的动作,账户进入 `valid` 状态。如果账户被客户端停用或者被服务器端撤销,将进入相应的状态:`deactivated``revoked`

```text
valid
|
|
+-----------+-----------+
Client | Server |
deactiv.| revoke |
V V
deactivated revoked
```

---

需要注意的是,根据服务器端具体的实现行为,上述的某些状态可能不会出现。例如:

* 如果服务器端签发证书的动作是同步的,那么订单就不会进入 `processing` 状态;
* 如果服务器端将已过期的授权立即删除,那么授权就不会进入 `expired` 状态。
91 changes: 91 additions & 0 deletions docs/state-machine.md
@@ -0,0 +1,91 @@
## 1. Challenge
Challenge objects are created in the "pending" state. They transition to the "processing" state when the client responds to the challenge (see Section 7.5.1) and the server begins attempting to validate that the client has completed the challenge. Note that within the "processing" state, the server may attempt to validate the challenge multiple times (see Section 8.2). Likewise, client requests for retries do not cause a state change. If validation is successful, the challenge moves to the "valid" state; if there is an error, the challenge moves to the "invalid" state.

```text
pending
|
| Receive
| response
V
processing <-+
| | | Server retry or
| | | client retry request
| +----+
|
|
Successful | Failed
validation | validation
+---------+---------+
| |
V V
valid invalid
```


## 2. Authorization
Authorization objects are created in the "pending" state. If one of the challenges listed in the authorization transitions to the "valid" state, then the authorization also changes to the "valid" state. If the client attempts to fulfill a challenge and fails, or if there is an error while the authorization is still pending, then the authorization transitions to the "invalid" state. Once the authorization is in the "valid" state, it can expire ("expired"), be deactivated by the client ("deactivated", see Section 7.5.2), or revoked by the server ("revoked").

```text
pending --------------------+
| |
Challenge failure | |
or | |
Error | Challenge valid |
+---------+---------+ |
| | |
V V |
invalid valid |
| |
| |
| |
+--------------+--------------+
| | |
| | |
Server | Client | Time after |
revoke | deactivate | "expires" |
V V V
revoked deactivated expired
```


## 3. Order
Order objects are created in the "pending" state. Once all of the authorizations listed in the order object are in the "valid" state, the order transitions to the "ready" state. The order moves to the "processing" state after the client submits a request to the order’s "finalize" URL and the CA begins the issuance process for the certificate. Once the certificate is issued, the order enters the "valid" state. If an error occurs at any of these stages, the order moves to the "invalid" state. The order also moves to the "invalid" state if it expires or one of its authorizations enters a final state other than "valid" ("expired", "revoked", or "deactivated").

```text
pending --------------+
| |
| All authz |
| "valid" |
V |
ready ---------------+
| |
| Receive |
| finalize |
| request |
V |
processing ------------+
| |
| Certificate | Error or
| issued | Authorization failure
V V
valid invalid
```


## 4. 账户 Account
Account objects are created in the "valid" state, since no further action is required to create an account after a successful newAccount request. If the account is deactivated by the client or revoked by the server, it moves to the corresponding state.

```text
valid
|
|
+-----------+-----------+
Client | Server |
deactiv.| revoke |
V V
deactivated revoked
```

---

Note that some of these states may not ever appear in a "status" field, depending on server behavior. For example, a server that issues synchronously will never show an order in the "processing" state. A server that deletes expired authorizations immediately will never show an authorization in the "expired" state.
6 changes: 3 additions & 3 deletions examples/example.php
Expand Up @@ -24,10 +24,10 @@
],
];

$client = new Client(['alert@example.com'], '../data/', TRUE);
$client = new Client(['alert@example.com'], '../data/', FALSE);

$order = $client->getOrder($domainInfo, CommonConstant::KEY_PAIR_TYPE_RSA);
// $order = $client->getOrder($domainInfo, CommonConstant::KEY_PAIR_TYPE_EC); // Issue an ECC certificate
$order = $client->getOrder($domainInfo, CommonConstant::KEY_PAIR_TYPE_RSA, TRUE);
// $order = $client->getOrder($domainInfo, CommonConstant::KEY_PAIR_TYPE_EC, TRUE); // Issue an ECC certificate

$challengeList = $order->getPendingChallengeList();

Expand Down

0 comments on commit 9069758

Please sign in to comment.