cacert-codedocs/source/signer.rst

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:

signer request message 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.

general request header format
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.

NUL request header format
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.

X.509 certificate signing request header format
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:

CA root certificate identifiers
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.

Certificate profile ids
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.

Message digest ids
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.

OpenPGP key signing request header format
Byte Value
0 Version (0x01)
1 Action (0x01)
2 System (0x02 for OpenPGP)
3 0x00
4 0x00
5 0x022
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:

signer response message 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.

general response header format
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>.

NUL response header 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>.

X.509 certificate response header 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>.

OpenPGP key signature response header 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>.

X.509 certificate revocation response header 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

  1. client sends 1 byte 0x02 to serial port
  2. client reads 1 byte from serial port (with a 20 second timeout)
  3. 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 the signer-request-data-format

  1. client builds byte wise xor of all data bytes into 1 byte $xor
  2. client sends concatenated $data string + xor-Byte + "rie4Ech7"
  3. client reads 1 byte (with a 5 second timeout)
  4. if received byte is 0x11 try again
  5. 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>

  1. client waits for a response (with a 120 second timeout)
  2. server builds byte wise xor of all data bytes in 1 byte $xor
  3. server sends 0x02 to start transmission
  4. client sends 0x10 to confirm receipt (server timeout 1 second)
  5. server sends concatenated $data string + xor-Byte + "rie4Ech7"
  6. client reads data in 100 byte segments (5 second timeout)
  7. client sends 0x11 in case of corrupted data and retries reading
  8. client sends 0x10 if successful
  9. server waits for response for 5 seconds
  10. 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"];

}


  1. the field is unused in server.pl <commmodule-server-pl>↩︎

  2. the field is unused in server.pl <commmodule-server-pl>↩︎

  3. this response type uses the same action byte as the OpenPGP key signature response message <signer-openpgp-response-format>↩︎