-.TH zpm-sign 8 2019-02-15 "ZPM 0.3"
+.TH zpm-sign 8 2019-03-09 "ZPM 0.7.0"
.SH NAME
zpm-sign \- manage package signatures
.SH SYNOPSIS
.B zpm sign
[
-.B -hrdsgev
+.B \-vsge
]
[
-.BI -f " sigfile"
+.B \-Hhrd
]
[
.BI -o " outfile"
]
[
-.BI -S " sigstring"
+.BI -i " input"
]
[
-.BI -k " keystring"
+.BI -k " keyid"
]
[
-.BI -K " keyfile"
+.BI -I " inputhexstring"
]
[
.BI -p " passphrase"
manages signatures on zpm packages. It can generate signing keys,
sign files, and verify signatures. The ed25519 algorithms are
used exclusively, and all the signature code is taken from the
-ref10 implementation. Signatures themselves are hex encoded
-representions of the signature metadata and the actual signature value.
+ref10 implementation.
.PP
Private keys are potentially encrypted with chacha20 before storing
them on disk.
+.PP
+Signatures are always detached signatures.
+.SS Specifying a key
+The \-k option is used to specify a key. Keys are looked for
+in the keyring file (or taken literally from the command line
+if the \-h option is given).
+The \-i option can be used to specify a
+key file to look for a key in. If the \-k option is given, or the ZPM_KEY
+environment variable is set, a key which matches that string in the id portion
+of the key is looked for, otherwise the first secret key found is used. If the
+\-i option is not given, a key will be searched for in a file given with the
+ZPM_KEYFILE environment variable or in ~/.zpm/key Alternatively, a hex encoded
+private key can be specified directly with the \-I option. If several of these
+options apply, The \-I option takes precedence. I.e. command line beats
+environment variables beats defaults.
+.PP
+If the private key needs a passphrase, it can be specified via the \-p
+option or the ZPM_KEYPASS environment variable, neither of which
+is secure. Otherwise, if /dev/tty can be opened, zpm-sign will
+attempt to ask for a passphrase.
+.PP
+For signing or generating a public key, a private key is looked for, and if not
+specified, the first one found in the keyring file is used.
+.PP
+For signature verification, no key needs to be specified as the public
+key is contained in the signature.
+.SS Signing Mode
+To sign data, use \-s
+.PP
+Inputs to a regular signature are:
+.TP the secret key used to sign the message,
+See above for methods to specify a secret key.
+.TP
+Signature timestamp
+Defaults to the current time read from the system clock.
+Can be specified with the \-T option.
+.TP
+Expiration timestamp
+Defaults to never. Can be specified with the \-E optino.
+.TP
+The message to be signed.
+Is read from stdin, a command line argument, or the \-m option.
+If both an argument and a \-m option are given the \-m option wins.
+.PP
+When a raw signature is created (with the \-r option), the
+.PP
+The signature is output to stdout, or the output file given with the
+\-o option. A signature packet is output unless the \-b option is given,
+in which case only the hex encoded signature is output.
+.SS Key Generation Mode
+A new private key is generated with \-g
+.SS Verification Mode
+A signature can be verified with \-v
.SH OPTIONS
+.TP
.B -r
+Output the raw signature or key data without wrapping it in a
+packet structure.
.TP
.B \-g
Generate a private key
This also just signs the data given, without any signature
metadata.
.TP
-.BI \-p passphrase
-Specify a passphrase to decrypt a private key.
+.BI \-p " passphrase"
+Specify a passphrase to decrypt or encrypt a private key. If not given here,
+the environment variable ZPM_SIGN_PP is used. Neither of these options
+are very secure, the command line in particular is generally readable
+by other processes.
.TP
-.BI \-m message
+.BI \-m " message"
Specify a message to be signed or verified. If not set with the -m option, the
message is taken from file named with the first non-option argument.
.TP
-.BI \-k path
+.BI \-k " path"
Take the private key for message signing from the path given. This
defaults to ~/.zpm/key. If ~/.zpm/key is not found and the euid
is root, /var/lib/zpm/key is tried.
.TP
-.BI \-K key
+.BI \-K " key"
Take the private key from the command line argument. This is not
particularly secure and is primarily intended for testing.
.TP
-.BI \-S sigstring
+.BI \-S " sigstring"
Use sigstring as the signature to verify.
.TP
-.BI \-m message
+.BI \-m " message"
Specify a message to be signed or verified. If not set with the -m option, the
message is taken from file named with the first non-option argument.
+.TP
+.BI \-t " timestamp"
+Specify a timestamp to be used for signing instead of the current time.
+Must be specified as a decimal representation of the unix timestamp
+to be used.
+.SH PACKET AND FILE FORMAT
+.PP
+Signatures and keys are output as hexencoded packet bytestrings. All are 256
+bytes, (512 bytes as hex encoded). Reserved bytes in packet formats must be
+zero. The last 8 bytes are reserved.
+.PP
+On disk format is a series of 32 bytes, hex encoded, followed by
+a newline. This takes one line per 32 bytes, thus 4 lines for 128,
+8 lines for 256. If we waste 8 bytes at the end, we have 8 lines
+and 512 bytes encoded, the last line will be short by 16 characters,
+so that the actual size on disk is 512 bytes.
+.PP
+Timestamps are 8 byte little endian integers of seconds since the epoch. or
+unix time, or some such. Times are a mess. Unix time is leap second unaware,
+and ambiguous during leap seconds. UTC requires a database of leap seconds for
+past time, and the specified second in the future possibly changes. TAI is
+good, but currently 37 seconds behind UTC, which is just weird.
+.PP
+All key and signature data begin with an 8 byte header, consisting of
+the following:
+.EX
+5A 50 4D 53 = "ZPMS" in ascii.
+01 = one byte version number
+xx = one byte packet type
+xx xx = two bytes packet information
+.EE
+.PP
+There are the following packet types.
+.SS Private Keys
+The public key is derivable from the secret key, so the public key is not
+explicitly stored.
+.EX
+private key format is:
+"ZPMS" 4 byte magic "ZPMS"
+byte 0x01 = version 1
+byte 0x01 = private key
+byte 0x01 = chacha encrypted, 0x00 = plain/raw key bytes
+byte 0x00 reserved, probably "key usage"
+32 bytes private key
+8 bytes creation time, little endian
+8 bytes expiration time, little endian
+8 bytes password salt, note, nist wants 16, but we're not using nist
+approved hash algorithms anyway.
+64 bytes reserved
+could have 16 bytes of IV for chacha to encrypt.
+Can probably use those, hashed with the password as the salt, but
+not very much salt then.
+120 bytes id
+8 bytes reserved trailer
+.EE
+.SS Public Keys
+.EX
+public key format is:
+"ZPMS" 4 byte magic "ZPMS"
+0x01 1 byte version
+0x02 1 byte "public key packet"
+0x00 1 byte reserved
+0x00 1 byte reserved
+0x.. 32 bytes public key
+0x.. 24 bytes reserved : create, expire, 8 reserved
+0x.. 64 bytes reserved : self sig
+ 120 bytes reserved : id = 1 byte id length, n bytes id, zeros
+ 8 bytes reserved trailer
+0x.. revocation signatures
+0x.. user id packets
+0x.. certification signatures
+0x.. sub key packets
+.EE
+.SS Signatures
+Data, Key, and Revocation signatures all have the same format,
+with the exception of the packet type byte at offset 5. Type
+0x03 is a data signature used for signing arbitrary data. Type
+0x04 is a key signature used to sign public keys. Type 0x05 is
+a revocation signature, used to revoke signatures.
+.EX
+"ZPMS" 4 byte magic "ZPMS"
+0x01 1 byte version
+0x03 1 byte "signature packet"
+0x00 1 byte reserved
+0x00 1 byte reserved
+0x.. 8 bytes timestamp of signature time
+0x.. 8 bytes timestamp of signature expiration, 0 if none
+0x.. 64 bytes of actual signature
+0x.. 32 bytes of public key making the signature
+0x.. 8 bytes reserved
+ 120 bytes reserved
+ 8 bytes reserved trailer
+.EE
.SH EXAMPLES
.TP
-.B zpm sign
-lists all files in the local database
+.B zpm sign -s \fIpath\fR
+Sign the contents of the file found at \fIpath\fR using the default secret key
+with a signing timestamp of the current time and no expiration date. The
+signature packet will be written to stdout.
+.TP
+.B zpm sign -s -m 'foo'
+Sign the string 'foo'.
+.TP
+.B printf '%s' foo | zpm sign -s
+Sign the string 'foo' as in the above example, the message being read
+from stdin.
+.TP
+.B zpm sign -s -r -m 'foo'
+Sign the string 'foo' directly using the default private key, no
+additional information is signed, and the output is a hex encoded
+raw signature with no additional newlines, making up 128 characters
+of output. There is no way to output just the raw signature while
+still adding the timestamps and such, but the raw signature can be
+extracted from a signature packet.
+.TP
+.B zpm sign -s -r \\
+-I 'c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7' \\
+-h -m 'af82'
+Sign the two byte hex encoded message af82 with the raw hex encoded
+secret key given by the -I argument. The result will be
+6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac
+18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a
+all on a single line with no trailing newline.
.SH EXIT STATUS
0 on success non zero on failure
+.SH BUGS
+.PP
+Timestamps are a mess. Unix time is leap second unaware, and ambiguous during
+leap seconds. UTC requires a database of leap seconds for past time, and the
+specified second in the future possibly changes. TAI is good, but currently 37
+seconds behind UTC, which is just weird. Regardless of the above, unix
+time was chosen for general compatibility with time functions.
+.PP
+There is no binding of a notion of an identity to a public key.
+.PP
+There is no trust level of a public key. A reserved byte could be
+used for this, but the semantics then need to be designed.
+.SH NOTES ON CRYPTOGRAPHY
+The general methods described by SEC 1 Ver 2.0 were followed, but
+this is not an implementation of that scheme, because different
+algorithms are used.
+.PP
+Chacha20 is used to encrypt private keys.
.SH FILES
-/var/lib/zpm/local.db
+~/.zpm/keys
+/var/lib/zpm/keys
.SH ENVIRONMENT
-ZPMDB
+ZPM_KEYRING
.SH AUTHOR
Nathan Wagner
.SH SEE ALSO
.BR zpm (8)
+.R RFC
+.R http://www.secg.org SEC 1 Ver 2.0