djm@openbsd.org | 2a9c9f7 | 2019-09-03 08:34:19 +0000 | [diff] [blame] | 1 | This document describes a lightweight SSH Signature format |
| 2 | that is compatible with SSH keys and wire formats. |
| 3 | |
| 4 | At present, only detached and armored signatures are supported. |
| 5 | |
| 6 | 1. Armored format |
| 7 | |
| 8 | The Armored SSH signatures consist of a header, a base64 |
| 9 | encoded blob, and a footer. |
| 10 | |
djm@openbsd.org | d637c4a | 2019-09-03 08:35:27 +0000 | [diff] [blame] | 11 | The header is the string "-----BEGIN SSH SIGNATURE-----" |
djm@openbsd.org | 2a9c9f7 | 2019-09-03 08:34:19 +0000 | [diff] [blame] | 12 | followed by a newline. The footer is the string |
djm@openbsd.org | d637c4a | 2019-09-03 08:35:27 +0000 | [diff] [blame] | 13 | "-----END SSH SIGNATURE-----" immediately after a newline. |
djm@openbsd.org | 2a9c9f7 | 2019-09-03 08:34:19 +0000 | [diff] [blame] | 14 | |
| 15 | The header MUST be present at the start of every signature. |
| 16 | Files containing the signature MUST start with the header. |
| 17 | Likewise, the footer MUST be present at the end of every |
| 18 | signature. |
| 19 | |
| 20 | The base64 encoded blob SHOULD be broken up by newlines |
| 21 | every 76 characters. |
| 22 | |
| 23 | Example: |
| 24 | |
| 25 | -----BEGIN SSH SIGNATURE----- |
| 26 | U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgJKxoLBJBivUPNTUJUSslQTt2hD |
| 27 | jozKvHarKeN8uYFqgAAAADZm9vAAAAAAAAAFMAAAALc3NoLWVkMjU1MTkAAABAKNC4IEbt |
| 28 | Tq0Fb56xhtuE1/lK9H9RZJfON4o6hE9R4ZGFX98gy0+fFJ/1d2/RxnZky0Y7GojwrZkrHT |
| 29 | FgCqVWAQ== |
| 30 | -----END SSH SIGNATURE----- |
| 31 | |
| 32 | 2. Blob format |
| 33 | |
| 34 | #define MAGIC_PREAMBLE "SSHSIG" |
| 35 | #define SIG_VERSION 0x01 |
| 36 | |
| 37 | byte[6] MAGIC_PREAMBLE |
| 38 | uint32 SIG_VERSION |
| 39 | string publickey |
| 40 | string namespace |
| 41 | string reserved |
| 42 | string hash_algorithm |
| 43 | string signature |
| 44 | |
| 45 | The publickey field MUST contain the serialisation of the |
| 46 | public key used to make the signature using the usual SSH |
| 47 | encoding rules, i.e RFC4253, RFC5656, |
| 48 | draft-ietf-curdle-ssh-ed25519-ed448, etc. |
| 49 | |
| 50 | Verifiers MUST reject signatures with versions greater than those |
| 51 | they support. |
| 52 | |
| 53 | The purpose of the namespace value is to specify a unambiguous |
| 54 | interpretation domain for the signature, e.g. file signing. |
| 55 | This prevents cross-protocol attacks caused by signatures |
| 56 | intended for one intended domain being accepted in another. |
| 57 | The namespace value MUST NOT be the empty string. |
| 58 | |
| 59 | The reserved value is present to encode future information |
| 60 | (e.g. tags) into the signature. Implementations should ignore |
| 61 | the reserved field if it is not empty. |
| 62 | |
| 63 | Data to be signed is first hashed with the specified hash_algorithm. |
| 64 | This is done to limit the amount of data presented to the signature |
| 65 | operation, which may be of concern if the signing key is held in limited |
| 66 | or slow hardware or on a remote ssh-agent. The supported hash algorithms |
| 67 | are "sha256" and "sha512". |
| 68 | |
| 69 | The signature itself is made using the SSH signature algorithm and |
| 70 | encoding rules for the chosen key type. For RSA signatures, the |
| 71 | signature algorithm must be "rsa-sha2-512" or "rsa-sha2-256" (i.e. |
| 72 | not the legacy RSA-SHA1 "ssh-rsa"). |
| 73 | |
| 74 | This blob is encoded as a string using the RFC4243 encoding |
| 75 | rules and base64 encoded to form the middle part of the |
| 76 | armored signature. |
| 77 | |
| 78 | |
| 79 | 3. Signed Data, of which the signature goes into the blob above |
| 80 | |
| 81 | #define MAGIC_PREAMBLE "SSHSIG" |
| 82 | |
| 83 | byte[6] MAGIC_PREAMBLE |
| 84 | string namespace |
| 85 | string reserved |
| 86 | string hash_algorithm |
| 87 | string H(message) |
| 88 | |
| 89 | The preamble is the six-byte sequence "SSHSIG". It is included to |
| 90 | ensure that manual signatures can never be confused with any message |
| 91 | signed during SSH user or host authentication. |
| 92 | |
| 93 | The reserved value is present to encode future information |
| 94 | (e.g. tags) into the signature. Implementations should ignore |
| 95 | the reserved field if it is not empty. |
| 96 | |
| 97 | The data is concatenated and passed to the SSH signing |
| 98 | function. |
| 99 | |