Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ jobs:

- name: test
run: |
bin/appletls_pem_test
bin/appletls_test
bin/curl -v -X HEAD http://example.com/
bin/curl -v -X HEAD https://example.com/

Expand Down
19 changes: 18 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,12 @@ hrpc_calc_server: prepare hrpc_calc_protoc



unittest: prepare libhv
APPLE_TLS_UNITTESTS =
ifeq ($(shell uname -s),Darwin)
APPLE_TLS_UNITTESTS += appletls_pem_test appletls_test
endif

unittest: prepare libhv $(APPLE_TLS_UNITTESTS)
$(CC) -g -Wall -O0 -std=c99 -I. -Ibase -o bin/rbtree_test unittest/rbtree_test.c base/rbtree.c
$(CC) -g -Wall -O0 -std=c99 -I. -Ibase -o bin/hbase_test unittest/hbase_test.c base/hbase.c
$(CC) -g -Wall -O0 -std=c99 -I. -Ibase -o bin/mkdir_p unittest/mkdir_test.c base/hbase.c
Expand Down Expand Up @@ -423,6 +428,18 @@ ifeq ($(WITH_REDIS), yes)
$(CXX) -g -Wall -O0 -std=c++11 -I. -Ibase -Issl -Ievent -Icpputil -Iredis -Ievpp -o bin/redis_subscriber_test unittest/redis_subscriber_test.cpp unittest/redis_test_server.cpp -Llib -lhv -pthread
endif
endif

appletls_pem_test: prepare
$(CC) -g -Wall -Wextra -O0 -std=c99 -DAPPLETLS_PEM_TESTING -I. -Ibase -Issl \
-o bin/appletls_pem_test unittest/appletls_pem_test.c ssl/appletls_pem.c

ifeq ($(shell uname -s),Darwin)
appletls_test: prepare
$(CC) -g -Wall -Wextra -O0 -std=c99 -DAPPLETLS_TESTING \
-I. -Ibase -Issl -Ievent -o bin/appletls_test \
unittest/appletls_test.c ssl/appletls.c ssl/appletls_pem.c \
-framework CoreFoundation -framework Security
endif
ifeq ($(WITH_LUA), yes)
$(CXX) -g -Wall -O0 -std=c++11 -DWITH_LUA $(LUA_CFLAGS) -I. -Ibase -Issl -Ievent -Icpputil -Ievpp -Ilua -o bin/lua_binding_test unittest/lua_binding_test.cpp -Llib -lhv -pthread $(LUA_LIBS)
$(CXX) -g -Wall -O0 -std=c++11 -DWITH_LUA $(LUA_CFLAGS) -I. -Ibase -Issl -Ievent -Icpputil -Ievpp -Ilua -o bin/lua_io_test unittest/lua_io_test.cpp -Llib -lhv -pthread $(LUA_LIBS)
Expand Down
33 changes: 33 additions & 0 deletions docs/cn/TcpClient.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,36 @@ class TcpClient {
```

测试代码见 [evpp/TcpClient_test.cpp](../../evpp/TcpClient_test.cpp)

## TLS 证书验证

`withTLS()` 默认只启用 TLS,不验证对端证书。需要验证服务端身份时,
将 `verify_peer` 设为 `1`:

```cpp
hssl_ctx_opt_t ssl = {};
ssl.verify_peer = 1;
client.withTLS(&ssl);
```

Apple TLS 后端在未设置 `ca_file` 和 `ca_path` 时使用系统信任根;设置了
任一项时,仅信任指定的自定义 CA,不再使用系统信任根。`ca_file` 可以
包含多个 PEM `CERTIFICATE` 块,`ca_path` 指向包含 PEM 或 DER CA 证书的
普通文件目录。通过域名连接时,Apple TLS 后端还会校验证书中的 DNS
主机名。验证时不会在线下载缺失的中间证书,服务端应发送完整证书链。

客户端双向 TLS 示例:

```cpp
hssl_ctx_opt_t ssl = {};
ssl.crt_file = "cert/client-chain.pem";
ssl.key_file = "cert/client.key";
ssl.ca_file = "cert/server-ca.pem";
ssl.verify_peer = 1;
client.withTLS(&ssl);
```

Apple TLS 后端的本地身份目前只支持未加密的 RSA 私钥:
`RSA PRIVATE KEY`(PKCS#1)或 RSA `PRIVATE KEY`(PKCS#8)。不支持 EC
私钥和加密私钥。加载本地身份要求 macOS 10.12 或 iOS 11.2 及以上;
不加载客户端身份时仍可在更早的系统版本上使用客户端 TLS。
34 changes: 34 additions & 0 deletions docs/cn/TcpServer.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,37 @@ class TcpServer {
```

测试代码见 [evpp/TcpServer_test.cpp](../../evpp/TcpServer_test.cpp)

## TLS 证书与双向认证

TLS 服务端必须提供证书链和对应私钥:

```cpp
hssl_ctx_opt_t ssl = {};
ssl.crt_file = "cert/server-chain.pem";
ssl.key_file = "cert/server.key";
server.withTLS(&ssl);
```

证书链文件使用 PEM 格式,第一张为服务端证书,后续依次为中间证书。

Apple TLS 后端将 `verify_peer` 设为 `1` 时会启用强制双向 TLS:客户端
必须提供受信任的证书,否则握手失败。

```cpp
hssl_ctx_opt_t ssl = {};
ssl.crt_file = "cert/server-chain.pem";
ssl.key_file = "cert/server.key";
ssl.ca_file = "cert/client-ca.pem";
ssl.verify_peer = 1;
server.withTLS(&ssl);
```

Apple TLS 后端在未设置 `ca_file` 和 `ca_path` 时使用系统信任根;设置了
任一项时,仅信任指定的自定义 CA。`ca_file` 可以包含多张 PEM 证书,
`ca_path` 指向包含 PEM 或 DER CA 证书的普通文件目录。其他 TLS 后端的
证书验证和 CA 目录格式由相应后端实现决定。

Apple TLS 后端的本地身份目前只支持未加密的 RSA 私钥:
`RSA PRIVATE KEY`(PKCS#1)或 RSA `PRIVATE KEY`(PKCS#8)。不支持 EC
私钥和加密私钥,且服务端身份要求 macOS 10.12 或 iOS 11.2 及以上。
6 changes: 5 additions & 1 deletion event/tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,11 @@ int tls_client_handshake_start(hio_t* io) {
sni = io->hostname;
}
if (sni) {
hssl_set_sni_hostname(io->ssl, sni);
if (hssl_set_sni_hostname(io->ssl, sni) != HSSL_OK) {
io->error = ERR_SSL_HANDSHAKE;
hio_close(io);
return -1;
}
}

io->phase = HIO_PHASE_TLS_CLIENT_HANDSHAKING;
Expand Down
6 changes: 5 additions & 1 deletion http/client/HttpClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,11 @@ static int http_client_ssl_handshake(http_client_t* cli, int connfd, const char*
return NABS(ERR_NEW_SSL);
}
if (sni_host && !is_ipaddr(sni_host)) {
hssl_set_sni_hostname(cli->ssl, sni_host);
if (hssl_set_sni_hostname(cli->ssl, sni_host) != HSSL_OK) {
hssl_free(cli->ssl);
cli->ssl = NULL;
return NABS(ERR_SSL_HANDSHAKE);
}
}
#ifdef WITH_OPENSSL
// Offer ALPN "h2" only when HTTP/2 is intended, so an h2-capable server
Expand Down
6 changes: 6 additions & 0 deletions scripts/unittest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ bin/hurl_test
# bin/hthread_test
# bin/hmutex_test
bin/socketpair_test
if [ -x bin/appletls_pem_test ]; then
bin/appletls_pem_test || exit $?
fi
if [ "$(uname -s)" = "Darwin" ] && [ -x bin/appletls_test ]; then
bin/appletls_test || exit $?
Comment thread
ithewei marked this conversation as resolved.
fi
# bin/threadpool_test
# bin/objectpool_test
bin/sizeof_test
Expand Down
Loading
Loading