.TH zpm-sign 8 2019-03-09 "ZPM 0.7.0" .SH NAME zpm-sign \- manage package signatures .SH SYNOPSIS .B zpm sign [ .B \-vsge ] [ .B \-Hhrd ] [ .BI -o " outfile" ] [ .BI -i " input" ] [ .BI -k " keyid" ] [ .BI -I " inputhexstring" ] [ .BI -p " passphrase" ] [ .BI -m " messagestring" ] .RI [ file ] .SH DESCRIPTION \fBzpm-sign\fR 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. .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 .TP .B \-e Extract a public key from a private key. .TP .B \-s Sign a file or message. In addition to the message to be signed, signature metadata is signed. .TP .B \-v Verify a signature on a file or message. .TP .B \-h hexencode values .TP .B \-d Increase the debug level. May be given more than once. .TP .B \-r Output the raw signature, rather than a full zpm certificate. This also just signs the data given, without any signature metadata. .TP .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" 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" 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" Take the private key from the command line argument. This is not particularly secure and is primarily intended for testing. .TP .BI \-S " sigstring" Use sigstring as the signature to verify. .TP .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 -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 ~/.zpm/keys /var/lib/zpm/keys .SH ENVIRONMENT ZPM_KEYRING .SH AUTHOR Nathan Wagner .SH SEE ALSO .BR zpm (8) .R RFC .R http://www.secg.org SEC 1 Ver 2.0