cacert-gosigner/docs/design.md

151 lines
6.6 KiB
Markdown
Raw Normal View History

2022-08-02 09:15:23 +00:00
# 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