summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Unangst <tedu@cvs.openbsd.org>2014-01-09 15:36:41 +0000
committerTed Unangst <tedu@cvs.openbsd.org>2014-01-09 15:36:41 +0000
commitb422cd1a6d702f4585312273eb62df15c6f1d5f8 (patch)
tree346b7f277b1ae22428f155789ff1ba06de7cd230
parent6d543d5617c51d69ec1399c4c834ee01e4939941 (diff)
-e embedded signatures. ok deraadt
-rw-r--r--usr.bin/signify/signify.117
-rw-r--r--usr.bin/signify/signify.c100
2 files changed, 83 insertions, 34 deletions
diff --git a/usr.bin/signify/signify.1 b/usr.bin/signify/signify.1
index 6045c0176c1..9f8397a1e48 100644
--- a/usr.bin/signify/signify.1
+++ b/usr.bin/signify/signify.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: signify.1,v 1.7 2014/01/03 17:10:27 espie Exp $
+.\" $OpenBSD: signify.1,v 1.8 2014/01/09 15:36:40 tedu Exp $
.\"
.\"Copyright (c) 2013 Marc Espie <espie@openbsd.org>
.\"Copyright (c) 2013 Ted Unangst <tedu@openbsd.org>
@@ -14,7 +14,7 @@
.\"WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
.\"ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\"OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-.Dd $Mdocdate: January 3 2014 $
+.Dd $Mdocdate: January 9 2014 $
.Dt SIGNIFY 1
.Os
.Sh NAME
@@ -27,21 +27,23 @@
.Fl s Ar seckey
.Fl G
.Nm signify
+.Op Fl e
.Op Fl o Ar output
.Fl s Ar seckey
.Fl S
-.Ar input
+.Ar message
.Nm signify
+.Op Fl e
.Op Fl o Ar output
.Fl p Ar pubkey
.Fl V
-.Ar input
+.Ar message
.Sh DESCRIPTION
The
.Nm
utility creates and verifies cryptographic signatures for
an input file
-.Ar input .
+.Ar message .
The mode of operation is selected by the
.Fl G ,
.Fl S ,
@@ -51,6 +53,9 @@ options.
.Pp
The options are as follows:
.Bl -tag -width Dssoutput
+.It Fl e
+Embed the message after the signature when signing.
+For verification, extract the message from the signature.
.It Fl G
Generate a new keypair.
.It Fl n
@@ -58,7 +63,7 @@ Do not ask for a passphrase during key generation.
Otherwise,
.Nm
will prompt the user for a passphrase on the terminal.
-.It Fl o Ar output
+.It Fl o Ar sigfile
The signature file to create or verify.
The default is
.Ar input Ns .sig .
diff --git a/usr.bin/signify/signify.c b/usr.bin/signify/signify.c
index 72ffdccdc97..3710dc81f83 100644
--- a/usr.bin/signify/signify.c
+++ b/usr.bin/signify/signify.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: signify.c,v 1.15 2014/01/08 07:04:29 espie Exp $ */
+/* $OpenBSD: signify.c,v 1.16 2014/01/09 15:36:40 tedu Exp $ */
/*
* Copyright (c) 2013 Ted Unangst <tedu@openbsd.org>
*
@@ -72,9 +72,9 @@ usage(void)
fprintf(stderr, "usage:"
#ifndef VERIFYONLY
"\t%s [-n] -p pubkey -s seckey -G\n"
- "\t%s [-o output] -s seckey -S input\n"
+ "\t%s [-e] [-o output] -s seckey -S input\n"
#endif
- "\t%s [-o output] -p pubkey -V input\n",
+ "\t%s [-e] [-o output] -p pubkey -V input\n",
#ifndef VERIFYONLY
__progname, __progname,
#endif
@@ -117,30 +117,43 @@ readall(int fd, void *buf, size_t len, const char *filename)
}
}
+static size_t
+parseb64file(const char *filename, char *b64, void *buf, size_t len)
+{
+ int rv;
+ char *commentend, *b64end;
+
+ commentend = strchr(b64, '\n');
+ if (!commentend || commentend - b64 <= COMMENTHDRLEN ||
+ memcmp(b64, COMMENTHDR, COMMENTHDRLEN))
+ errx(1, "invalid comment in %s; must start with '%s'",
+ filename, COMMENTHDR);
+ b64end = strchr(commentend + 1, '\n');
+ if (!b64end)
+ errx(1, "missing new line after b64 in %s", filename);
+ *b64end = 0;
+ rv = b64_pton(commentend + 1, buf, len);
+ if (rv != len)
+ errx(1, "invalid b64 encoding in %s", filename);
+ if (memcmp(buf, PKALG, 2))
+ errx(1, "unsupported file %s", filename);
+ return b64end - b64 + 1;
+}
+
static void
readb64file(const char *filename, void *buf, size_t len)
{
char b64[2048];
int rv, fd;
- char *commentend;
fd = xopen(filename, O_RDONLY | O_NOFOLLOW, 0);
memset(b64, 0, sizeof(b64));
rv = read(fd, b64, sizeof(b64) - 1);
if (rv == -1)
err(1, "read from %s", filename);
- commentend = strchr(b64, '\n');
- if (!commentend || commentend - b64 <= COMMENTHDRLEN ||
- memcmp(b64, COMMENTHDR, COMMENTHDRLEN))
- errx(1, "invalid comment in %s; must start with '%s'",
- filename, COMMENTHDR);
- rv = b64_pton(commentend + 1, buf, len);
- if (rv != len)
- errx(1, "invalid b64 encoding in %s", filename);
+ parseb64file(filename, b64, buf, len);
memset(b64, 0, sizeof(b64));
close(fd);
- if (memcmp(buf, PKALG, 2))
- errx(1, "unsupported file %s", filename);
}
uint8_t *
@@ -179,6 +192,16 @@ writeall(int fd, const void *buf, size_t len, const char *filename)
}
static void
+appendall(const char *filename, const void *buf, size_t len)
+{
+ int fd;
+
+ fd = xopen(filename, O_NOFOLLOW | O_RDWR | O_APPEND, 0);
+ writeall(fd, buf, len, filename);
+ close(fd);
+}
+
+static void
writeb64file(const char *filename, const char *comment, const void *buf,
size_t len, mode_t mode)
{
@@ -270,7 +293,8 @@ generate(const char *pubkeyfile, const char *seckeyfile, int rounds)
}
static void
-sign(const char *seckeyfile, const char *inputfile, const char *sigfile)
+sign(const char *seckeyfile, const char *msgfile, const char *sigfile,
+ int embedded)
{
struct sig sig;
uint8_t digest[SHA512_DIGEST_LENGTH];
@@ -297,7 +321,7 @@ sign(const char *seckeyfile, const char *inputfile, const char *sigfile)
errx(1, "incorrect passphrase");
memset(digest, 0, sizeof(digest));
- msg = readmsg(inputfile, &msglen);
+ msg = readmsg(msgfile, &msglen);
signmsg(enckey.seckey, msg, msglen, sig.sig);
memcpy(sig.fingerprint, enckey.fingerprint, FPLEN);
@@ -305,6 +329,8 @@ sign(const char *seckeyfile, const char *inputfile, const char *sigfile)
memcpy(sig.pkalg, PKALG, 2);
writeb64file(sigfile, "signature", &sig, sizeof(sig), 0666);
+ if (embedded)
+ appendall(sigfile, msg, msglen);
free(msg);
}
@@ -331,34 +357,49 @@ verifymsg(uint8_t *pubkey, uint8_t *msg, unsigned long long msglen,
static void
-verify(const char *pubkeyfile, const char *inputfile, const char *sigfile)
+verify(const char *pubkeyfile, const char *msgfile, const char *sigfile,
+ int embedded)
{
struct sig sig;
struct pubkey pubkey;
- unsigned long long msglen;
+ unsigned long long msglen, siglen = 0;
uint8_t *msg;
+ int fd;
+
+ msg = readmsg(embedded ? sigfile : msgfile, &msglen);
readb64file(pubkeyfile, &pubkey, sizeof(pubkey));
- readb64file(sigfile, &sig, sizeof(sig));
+ if (embedded) {
+ siglen = parseb64file(sigfile, msg, &sig, sizeof(sig));
+ msg += siglen;
+ msglen -= siglen;
+ } else {
+ readb64file(sigfile, &sig, sizeof(sig));
+ }
if (memcmp(pubkey.fingerprint, sig.fingerprint, FPLEN))
errx(1, "verification failed: checked against wrong key");
- msg = readmsg(inputfile, &msglen);
-
verifymsg(pubkey.pubkey, msg, msglen, sig.sig);
+ if (embedded) {
+ fd = xopen(msgfile, O_CREAT|O_EXCL|O_NOFOLLOW|O_RDWR, 0666);
+ writeall(fd, msg, msglen, msgfile);
+ close(fd);
+ }
+
printf("verified\n");
- free(msg);
+ free(msg - siglen);
}
int
main(int argc, char **argv)
{
- const char *pubkeyfile = NULL, *seckeyfile = NULL, *inputfile = NULL,
+ const char *pubkeyfile = NULL, *seckeyfile = NULL, *msgfile = NULL,
*sigfile = NULL;
char sigfilebuf[1024];
int ch, rounds;
+ int embedded = 0;
enum {
NONE,
GENERATE,
@@ -369,7 +410,7 @@ main(int argc, char **argv)
rounds = 42;
- while ((ch = getopt(argc, argv, "GSVno:p:s:")) != -1) {
+ while ((ch = getopt(argc, argv, "GSVeno:p:s:")) != -1) {
switch (ch) {
#ifndef VERIFYONLY
case 'G':
@@ -388,6 +429,9 @@ main(int argc, char **argv)
usage();
verb = VERIFY;
break;
+ case 'e':
+ embedded = 1;
+ break;
case 'n':
rounds = 0;
break;
@@ -426,11 +470,11 @@ main(int argc, char **argv)
if (argc != 1)
usage();
- inputfile = argv[0];
+ msgfile = argv[0];
if (!sigfile) {
if (snprintf(sigfilebuf, sizeof(sigfilebuf), "%s.sig",
- inputfile) >= sizeof(sigfilebuf))
+ msgfile) >= sizeof(sigfilebuf))
errx(1, "path too long");
sigfile = sigfilebuf;
}
@@ -438,13 +482,13 @@ main(int argc, char **argv)
if (verb == SIGN) {
if (!seckeyfile)
usage();
- sign(seckeyfile, inputfile, sigfile);
+ sign(seckeyfile, msgfile, sigfile, embedded);
} else
#endif
if (verb == VERIFY) {
if (!pubkeyfile)
usage();
- verify(pubkeyfile, inputfile, sigfile);
+ verify(pubkeyfile, msgfile, sigfile, embedded);
}
}