151 lines
6.6 KiB
Markdown
151 lines
6.6 KiB
Markdown
|
# Signer system design
|
||
|
|
||
|
This document describes the system design of the CAcert signer software. The document describes the integration as well
|
||
|
as technical design decisions.
|
||
|
|
||
|
## Context
|
||
|
|
||
|
The signer is used to handle X.509 certificate and OpenPGP public key signing, X.509 certificate revocation and CRL
|
||
|
handling. The signer receives commands via a serial link.
|
||
|
|
||
|
![C4 Context diagram of the Signer showing the interaction with the surrounding systems described in the sections below](container.svg "Signer Context diagram")
|
||
|
|
||
|
### WebDB
|
||
|
|
||
|
*WebDB* is the system running the user facing *WebDB application*. The *Signer client* that is part of the *WebDB*
|
||
|
system, polls certificate and public key signing as well as certificate revocation request information from the
|
||
|
*WebDB database* periodically. The *Signer client* takes care of fetching CRLs and health information from the
|
||
|
*Signer server* periodically.
|
||
|
|
||
|
The requests are send via a binary protocol (msgpack + COBS) over a serial link.
|
||
|
|
||
|
*Note:* the database polling may be replaced with an event broker like Redis or NATS in the future.
|
||
|
|
||
|
### Signer
|
||
|
|
||
|
The *Signer* system runs the signer software. The system is only reachable via a serial link from the outside.
|
||
|
Information coming over that connection is trusted in the sense that requested certificate attributes where checked by
|
||
|
the requesting *WebDB application*.
|
||
|
|
||
|
The *Signer Server* synchronizes with another Signer via a dedicated internal network link (crossover cable). The
|
||
|
synchronization is required to make information related to issued and revoked certificates available on both signers.
|
||
|
|
||
|
## Signer components
|
||
|
|
||
|
The Signer server is structured into several components with clear responsibilities.
|
||
|
|
||
|
![C4 Component diagram showing the components of the signer described in the sections below.](components.svg "Components of the signer")
|
||
|
|
||
|
The Singer server is implemented in [Go](https://golang.org/), configured via YAML and running as a standalone
|
||
|
process.
|
||
|
|
||
|
### Serial link handler
|
||
|
|
||
|
The serial link handler handles all communication over the serial link. It reads raw bytes and writes raw bytes, it
|
||
|
handles the serial link and takes care of connection and configuration.
|
||
|
|
||
|
The raw bytes are framed using
|
||
|
[Consistent Overhead Byte Stuffing (COBS)](https://en.wikipedia.org/wiki/Consistent_Overhead_Byte_Stuffing).
|
||
|
|
||
|
Frame data consists of msgpack formatted protocol messages and a CRC32 code to ensure integrity. Broken frames are
|
||
|
rejected with an error frame.
|
||
|
|
||
|
Used libraries:
|
||
|
- [github.com/tarm/serial](https://pkg.go.dev/github.com/tarm/serial)
|
||
|
- [github.com/justincpresley/go-cobs](https://pkg.go.dev/github.com/justincpresley/go-cobs)
|
||
|
|
||
|
### Protocol handler
|
||
|
|
||
|
The protocol handler receives [msgpack](https://msgpack.org/) information from the serial link handler and sends
|
||
|
msgpack information to the serial link handler.
|
||
|
|
||
|
The protocol handler inspects incoming msgpack messages and dispatches the parsed payload to the appropriate command
|
||
|
handler. The result from the command handler is serialized back to a msgpack message and sent to the serial link
|
||
|
handler.
|
||
|
|
||
|
Used library:
|
||
|
- [github.com/shamaton/msgpackgen](https://pkg.go.dev/github.com/shamaton/msgpackgen)
|
||
|
|
||
|
*TODO:* the protocol message have to be described in more detail
|
||
|
|
||
|
### X.509 signing handler
|
||
|
|
||
|
The X.509 signing handler takes care of X.509 certificate signing. It needs to support certificate profiles. The
|
||
|
profiles decide which attributes from the request are used/accepted, which is private key is used and which extensions
|
||
|
are set in the resulting certificate.
|
||
|
|
||
|
Actual signing is performed by the *HSM access* component. Signed certificate information is stored in the
|
||
|
*Certificate repository*.
|
||
|
|
||
|
### X.509 revocation handler
|
||
|
|
||
|
The X.509 revocation handler takes care of X.509 certificate revocation. It expects an issuer DN and serial number and
|
||
|
supports an optional revocation reason. The revocation handler marks the corresponding certificate as revoked in the
|
||
|
*Certificate repository*.
|
||
|
|
||
|
*Note:* CRLs are not generated immediately
|
||
|
|
||
|
### X.509 CRL handler
|
||
|
|
||
|
The X.509 CRL handler takes care of generating certificate revocation lists. The handler expects an issuer DN, checks
|
||
|
for non-expired, revoked certificates in the *Certificate repository* and generates a CRL.
|
||
|
|
||
|
The *HSM access* component is used to sign the CRL.
|
||
|
|
||
|
*TODO:* Clarify whether the CRL should contain expired certificates within a configurable grace period (see RFCs and
|
||
|
potential other reference material for guidance)
|
||
|
|
||
|
*TODO:* Do we need specific CRLs for specific certificate profiles (i.e. only for server certificates)?
|
||
|
|
||
|
### OpenPGP signing handler
|
||
|
|
||
|
The OpenPGP signing handler takes care of OpenPGP key signing.
|
||
|
|
||
|
Actual signing is performed by the *HSM access* component. Signed OpenPGP key information is stored in the
|
||
|
*Certificate repository*.
|
||
|
|
||
|
Used library:
|
||
|
- [github.com/ProtonMail/go-crypto/openpgp](https://pkg.go.dev/github.com/ProtonMail/go-crypto/openpgp)
|
||
|
|
||
|
### Health check handler
|
||
|
|
||
|
The Health check handler takes care of providing signer health information to the signer client. The health check data
|
||
|
contains:
|
||
|
|
||
|
- accessibility and consistency information of the *Certificate repository*
|
||
|
- expiry information for the signing certificates
|
||
|
- health information for the HSM
|
||
|
- version information
|
||
|
- current time of the signer
|
||
|
|
||
|
### HSM access
|
||
|
|
||
|
The HSM access component provides signing capabilities backed by HSMs (hardware security modules). It uses the PKCS#11
|
||
|
protocol to access the HSM hardware or SoftHSM.
|
||
|
|
||
|
Used libraries:
|
||
|
- [github.com/ThalesIgnite/crypto11](https://pkg.go.dev/github.com/ThalesIgnite/crypto11)
|
||
|
- SoftHSM2 (from [Debian package](https://tracker.debian.org/pkg/softhsm2))
|
||
|
- [OpenSC](https://github.com/OpenSC/OpenSC/wiki) (from [Debian package](https://tracker.debian.org/pkg/opensc)) for
|
||
|
access to [SmartCardHSM or NitroKey HSM](https://github.com/OpenSC/OpenSC/wiki/SmartCardHSM)
|
||
|
|
||
|
### Certificate repository
|
||
|
|
||
|
The certificate repository stores information about issued and revoked X.509 certificates as well as signed OpenPGP
|
||
|
keys.
|
||
|
|
||
|
*TODO:* define the data format for the certificate repository
|
||
|
|
||
|
Used library:
|
||
|
- [github.com/dgraph-io/badger/v3](https://pkg.go.dev/github.com/dgraph-io/badger/v3)
|
||
|
|
||
|
### Synchronization handler
|
||
|
|
||
|
The synchronization handler is used to synchronize state (signing, revocation and CRL issuing information) between
|
||
|
signers. The handler acts as a producer and consumer for synchronization messages. The message transport should use
|
||
|
a lightweight existing middleware like [NATS](https://nats.io/).
|
||
|
|
||
|
The synchronization handler may require support for replaying messages when a signer comes back after a service
|
||
|
interruption or when a new signer is set up.
|
||
|
|
||
|
*TODO:* specify the synchronization protocol in much more detail
|