summaryrefslogtreecommitdiff
path: root/usr.bin/gzsig/key.c
diff options
context:
space:
mode:
authormarius eriksen <marius@cvs.openbsd.org>2005-05-28 01:57:31 +0000
committermarius eriksen <marius@cvs.openbsd.org>2005-05-28 01:57:31 +0000
commit010931b7acab26046e0adaef4808f43f0a87050f (patch)
tree73441fc9a82db0aca0b0acfbf728d3aff9cc136b /usr.bin/gzsig/key.c
parent25f01a945904da779dc25261b49b8e79b32b6fb9 (diff)
import gzsig by Dug Song.
a bunch of lumberjack work, zapped support for keynote and SSH1 and added support for SSH2 keys. ok millert@ deraadt@
Diffstat (limited to 'usr.bin/gzsig/key.c')
-rw-r--r--usr.bin/gzsig/key.c216
1 files changed, 216 insertions, 0 deletions
diff --git a/usr.bin/gzsig/key.c b/usr.bin/gzsig/key.c
new file mode 100644
index 00000000000..b7909384e88
--- /dev/null
+++ b/usr.bin/gzsig/key.c
@@ -0,0 +1,216 @@
+/* $OpenBSD: key.c,v 1.1 2005/05/28 01:57:30 marius Exp $ */
+
+/*
+ * key.c
+ *
+ * Copyright (c) 2001 Dug Song <dugsong@arbor.net>
+ * Copyright (c) 2001 Arbor Networks, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the copyright holders may not be used to endorse or
+ * promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: key.c,v 1.1 2005/05/28 01:57:30 marius Exp $
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/uio.h>
+
+#include <openssl/ssl.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "key.h"
+#include "ssh2.h"
+#include "util.h"
+#include "x509.h"
+
+typedef int (*key_loader)(struct key *, struct iovec *);
+
+static key_loader pubkey_loaders[] = {
+ ssh2_load_public,
+ x509_load_public,
+ NULL
+};
+
+static key_loader privkey_loaders[] = {
+ x509_load_private,
+ NULL
+};
+
+static int
+load_file(struct iovec *iov, char *filename)
+{
+ struct stat st;
+ int fd;
+
+ if ((fd = open(filename, O_RDONLY)) < 0)
+ return (-1);
+
+ if (fstat(fd, &st) < 0)
+ return (-1);
+
+ if (st.st_size == 0) {
+ errno = EINVAL;
+ return (-1);
+ }
+ if ((iov->iov_base = malloc(st.st_size + 1)) == NULL)
+ return (-1);
+
+ iov->iov_len = st.st_size;
+ ((u_char *)iov->iov_base)[iov->iov_len] = '\0';
+
+ if (read(fd, iov->iov_base, iov->iov_len) != iov->iov_len) {
+ free(iov->iov_base);
+ return (-1);
+ }
+ close(fd);
+
+ return (0);
+}
+
+struct key *
+key_new(void)
+{
+ struct key *k;
+
+ if ((k = calloc(sizeof(*k), 1)) == NULL)
+ return (NULL);
+
+ return (k);
+}
+
+int
+key_load_private(struct key *k, char *filename)
+{
+ struct iovec iov;
+ int i;
+
+ if (load_file(&iov, filename) < 0)
+ return (-1);
+
+ for (i = 0; privkey_loaders[i] != NULL; i++) {
+ if (privkey_loaders[i](k, &iov) == 0)
+ return (0);
+ }
+ return (-1);
+}
+
+int
+key_load_public(struct key *k, char *filename)
+{
+ struct iovec iov;
+ int i;
+
+ if (load_file(&iov, filename) < 0)
+ return (-1);
+
+ for (i = 0; pubkey_loaders[i] != NULL; i++) {
+ if (pubkey_loaders[i](k, &iov) == 0)
+ return (0);
+ }
+ return (-1);
+}
+
+int
+key_sign(struct key *k, u_char *msg, int mlen, u_char *sig, int slen)
+{
+ switch (k->type) {
+ case KEY_RSA:
+ if (RSA_size((RSA *)k->data) > slen) {
+ fprintf(stderr, "RSA modulus too large: %d bits\n",
+ RSA_size((RSA *)k->data));
+ return (-1);
+ }
+ if (RSA_sign(NID_sha1, msg, mlen, sig, &slen,
+ (RSA *)k->data) <= 0) {
+ fprintf(stderr, "RSA signing failed\n");
+ return (-1);
+ }
+ break;
+
+ case KEY_DSA:
+ if (DSA_size((DSA *)k->data) > slen) {
+ fprintf(stderr, "DSA signature size too large: "
+ "%d bits\n", DSA_size((DSA *)k->data));
+ return (-1);
+ }
+ if (DSA_sign(NID_sha1, msg, mlen, sig, &slen,
+ (DSA *)k->data) <= 0) {
+ fprintf(stderr, "DSA signing failed\n");
+ return (-1);
+ }
+ break;
+
+ default:
+ fprintf(stderr, "Unknown key type: %d\n", k->type);
+ return (-1);
+ }
+ return (slen);
+}
+
+int
+key_verify(struct key *k, u_char *msg, int mlen, u_char *sig, int slen)
+{
+ switch (k->type) {
+
+ case KEY_RSA:
+ if (RSA_verify(NID_sha1, msg, mlen,
+ sig, slen, (RSA *)k->data) <= 0) {
+ fprintf(stderr, "RSA verification failed\n");
+ return (-1);
+ }
+ break;
+
+ case KEY_DSA:
+ if (DSA_verify(NID_sha1, msg, mlen,
+ sig, slen, (DSA *)k->data) <= 0) {
+ fprintf(stderr, "DSA verification failed\n");
+ return (-1);
+ }
+ break;
+
+ default:
+ fprintf(stderr, "Unknown key type: %d\n", k->type);
+ return (-1);
+ }
+ return (slen);
+}
+
+void
+key_free(struct key *k)
+{
+ if (k->type == KEY_RSA)
+ RSA_free((RSA *)k->data);
+ else if (k->type == KEY_DSA)
+ DSA_free((DSA *)k->data);
+ else if (k->data != NULL)
+ free(k->data);
+
+ free(k);
+}