diff options
author | marius eriksen <marius@cvs.openbsd.org> | 2005-05-28 01:57:31 +0000 |
---|---|---|
committer | marius eriksen <marius@cvs.openbsd.org> | 2005-05-28 01:57:31 +0000 |
commit | 010931b7acab26046e0adaef4808f43f0a87050f (patch) | |
tree | 73441fc9a82db0aca0b0acfbf728d3aff9cc136b /usr.bin/gzsig/key.c | |
parent | 25f01a945904da779dc25261b49b8e79b32b6fb9 (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.c | 216 |
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); +} |