14 KiB
The Signer Protocol
Communication with the signer is performed via a serial connection. That connection has to be established by the client before speaking the protocol defined here.
Signer request data format specification
Protocol request data is encoded in the following format:
Byte | Data |
---|---|
0-2 | length of header + data in network byte order |
3-5 | length of header network byte order |
6-14 | action specific header |
15-17 | length of first action specific content in network byte order |
18-N | fist action specific content string |
N+1-N+3 | length of second action specific content in network byte order |
N+4-M | second action specific content string |
M+1-M+3 | lenght of third action specific content in network byte order |
M+4-End | third action specific content string |
Due to the length encoding in 3 bytes the messages can have a maximum length of 83 = 224 Bytes which is around 16 MiB.
General request header format
Every protocol request header (bytes 3-12 of protocol request message) follows the same 9 byte structure. The content of bytes 3-8 are protocol action specific.
Byte | Value |
---|---|
0 | Version (0x01 ) |
1 | Action |
2 | System (used crypto system) |
3 | 8 bits root |
4 | 8 bits configuration |
5 | 8 bits parameter |
6-7 | 16 bits parameter |
8 | 8 bits parameter |
Format of NUL requests
NUL requests are sent at the end of each iteration in client.pl <commmodule-client-pl>
's main loop.
Byte | Value |
---|---|
0 | Version (0x01 ) |
1 | Action (0x00 ) |
2 | System (0x00 ) |
3 | 0x00 |
4 | 0x00 |
5 | 0x00 |
6-7 | 0x0000 |
8 | 0x00 |
NUL Request Payload:
- GMT timestamp in %m%d%H%M%Y.%S format
- ""
- ""
Note
The timestamp sent with the NUL request is used to create a script to synchronize the time on the signer using date
and hwclock
.
Format of X.509 signing request messages
X.509 signing request messages are sent in client.pl <commmodule-client-pl>
's main loop for each requested certificate.
Byte | Value |
---|---|
0 | Version (0x01 ) |
1 | Action (0x01 ) |
2 | System (0x01 for X.509) |
3 | Root (see table table-cert-roots ) |
4 | Profile (see table table-cert-profiles ) |
5 | Message Digest Id (see table table-md-ids ) |
6-7 | Days in big-endian format |
8 | Key type1 |
The key type is stored in the column keytype of the certificate request table which is one of
- domaincerts
- emailcerts
- orgdomaincerts
- orgemailcerts
X.509 Signing Request Payload:
- PEM encoded PKCS#10 /
2986
certifcate signing request or SPKAC (Netscape) signed public key and challenge (i.e. generated from a <keygen> HTML form element) - comma separated list of SubjectAlternative names in a format that is accepted by openssl configuration file directive
subjectAltName
(see https://www.openssl.org/docs/man1.0.2/apps/x509v3_config.html#Subject-Alternative-Name) - The requested subject DN in openssl format (parts separated by
/
)
Id | CA root |
---|---|
0 | CAcert root (aka CAcert class 1 root) |
1 | CAcert class3 |
2 | CAcert class3s |
x | root{} |
Note
The CA root identifier is retrieved from the database by client.pl <commmodule-client-pl>
the value that is found there is decremented by 1 before it is sent to the server.
The server in server.pl <commmodule-server-pl>
restricts the allowed root id in its CheckSystem
function.
Id | Profile |
---|---|
0 | Client (personal) |
1 | Client (Organization) |
2 | Client (Code signing) |
3 | Client (Machine) |
4 | Client (ADS) |
5 | Server (personal) |
6 | Server (Organization) |
7 | Server (Jabber) |
8 | Server (OCSP) |
9 | Server (Timestamp) |
10 | Proxy |
11 | SubCA |
Note
client.pl <commmodule-client-pl>
supports profiles 0, 1, 2, 4, 5, 6, 8 and 9 only.
Id | Algorithm |
---|---|
1 | MD5 |
2 | SHA-1 |
3 | RIPE-MD160 |
8 | SHA-256 |
9 | SHA-384 |
10 | SHA-512 |
Format of OpenPGP key signing request messages
OpenPGP key signing request messages are sent in client.pl <commmodule-client-pl>
's main loop for each requested OpenPGP key.
Byte | Value |
---|---|
0 | Version (0x01 ) |
1 | Action (0x01 ) |
2 | System (0x02 for OpenPGP) |
3 | 0x00 |
4 | 0x00 |
5 | 0x02 2 |
6-7 | 366 encoded as 0x016e |
8 | 0x00 |
OpenPGP Signing Request Payload:
- OpenPGP public keyring in binary format (see
4880
) - ""
- ""
Format of X.509 certificate revocation request messages
X.509 certificate revocation request messages are sent in client.pl <commmodule-client-pl>
's main loop for each requested X.509 certificate revocation.
Byte Value 0 Version ( 0x01
)1 Action ( 0x02
)2 System ( 0x01
for X.509)3 Root 4 0x00
5 0x00
6-7 365 encoded as 0x016d
8 0x00
X.509 Certificate Revocation Request Payload:
- PEM encoded certificate data of the certificate to be revoked
- ""
- hexadecimal encoded SHA-1 hash of the CRL known CRL file of the requested CA Root (header byte 3)
Signer response data format specification
Protocol response data is encoded in the following format:
Byte | Data |
---|---|
0-2 | length of header + data in network byte order |
3-5 | length of header network byte order |
6-9 | header data |
10-12 | length of payload data 1 in network byte order |
13-N | payload data 1 |
N+1-N+3 | length of payload data 2 network byte order |
N+4-M | payload data 2 |
M+1-M+3 | length of payload data 3 network byte order |
M+4-End | payload data 3 |
General response header format
Every protocol response header (bytes 6-9 of protocol response message) follows the same 4 byte structure. The content of bytes 3 and 4 are not used yet.
Byte | Value |
---|---|
0 | Version (0x01 ) |
1 | Action |
2 | 0x00 unused |
3 | 0x00 unused |
Format of NUL Responses
NUL responses are sent in response to NUL requests <signer-nul-request-format>
.
Byte | Value |
---|---|
0 | Version (0x01 ) |
1 | Action (0x00 ) |
2 | 0x00 unused |
3 | 0x00 unused |
NUL Response Payload:
- ""
- ""
- ""
Format of X.509 certificate response messages
X.509 certificate response messages are sent in response to X.509 certificate signing request messages <signer-x509-request-format>
.
Byte | Value |
---|---|
0 | Version (0x01 ) |
1 | Action (0x01 ) |
2 | 0x00 unused |
3 | 0x00 unused |
X.509 certificate response payload:
- PEM encoded X.509 certificate
- ""
- ""
Format of OpenPGP key signature response messages
OpenPGP key signature response messages are sent in response to OpenPGP key signing request messages <signer-openpgp-request-format>
.
Byte | Value |
---|---|
0 | Version (0x01 ) |
1 | Action (0x02 ) |
2 | 0x00 unused |
3 | 0x00 unused |
OpenPGP key signature response payload:
- ASCII armored PGP public key block
- ""
- ""
Format of X.509 certificate revocation response messages
X.509 certificate revocation response messages are sent in response to X.509 certificate revocation request messages
<signer-csr-request-format>
.
Byte | Value |
---|---|
0 | Version (0x01 ) |
1 | Action (0x02 )3 |
2 | 0x00 unused |
3 | 0x00 unused |
X.509 certificate revocation response payload:
- CRL diff in
xdelta
format or "" if the original CRL specified by the SHA-1 hash in the third payload field of the request is not available - ""
- ""
Protocol messages
Handshake
- client sends 1 byte
0x02
to serial port - client reads 1 byte from serial port (with a 20 second timeout)
- client checks whether the byte is
0x10
- seqdiag handhake {
client -> server [label = "0x02"]; client <-- server [label = "0x10"];
}
If anything different is received there was a protocol error and no further messages should be sent over the serial connection.
Send data
- Preconditions
successful
Handshake <signer-message-handshake>
, data is encoded according to thesigner-request-data-format
- client builds byte wise xor of all data bytes into 1 byte $xor
- client sends concatenated $data string + xor-Byte + "rie4Ech7"
- client reads 1 byte (with a 5 second timeout)
- if received byte is
0x11
try again - if received byte is
0x10
the message has been sent successfully
- seqdiag request_with_retry {
client -> client [label = "xor $data"]; client -> server [label = "$data . $xor . "rie4Ech7""]; server -> server [label = "detect corruption"]; client <-- server [label = "0x11"]; client -> server [label = "$data . $xor . "rie4Ech7""]; client <-- server [label = "0x10"];
}
If anything different is received there was a protocol error and no further messages should be sent over the serial connection.
Receive data
- Preconditions
client
sent data <signer-message-senddata>
- client waits for a response (with a 120 second timeout)
- server builds byte wise xor of all data bytes in 1 byte $xor
- server sends
0x02
to start transmission - client sends
0x10
to confirm receipt (server timeout 1 second) - server sends concatenated $data string + xor-Byte + "rie4Ech7"
- client reads data in 100 byte segments (5 second timeout)
- client sends
0x11
in case of corrupted data and retries reading - client sends
0x10
if successful - server waits for response for 5 seconds
- server sends concatenated $data string + xor-Byte + "rie4Ech7" if client response is
0x11
- seqdiag response_with_retry {
client -> server [label = "wait"]; server -> server [label = "xor $data"]; client <- server [label = "0x02"]; client --> server [label = "0x10"]; client <- server [label = "$data . $xor . "rie4Ech7""]; client -> client [label = "detect corruption"]; client --> server [label = "0x11"]; client <- server [label = "$data . $xor . "rie4Ech7""]; client --> server [label = "0x10"];
}