Annotation of src/usr.bin/gzsig/key.c, Revision 1.1
1.1 ! marius 1: /* $OpenBSD$ */
! 2:
! 3: /*
! 4: * key.c
! 5: *
! 6: * Copyright (c) 2001 Dug Song <dugsong@arbor.net>
! 7: * Copyright (c) 2001 Arbor Networks, Inc.
! 8: *
! 9: * Redistribution and use in source and binary forms, with or without
! 10: * modification, are permitted provided that the following conditions
! 11: * are met:
! 12: *
! 13: * 1. Redistributions of source code must retain the above copyright
! 14: * notice, this list of conditions and the following disclaimer.
! 15: * 2. Redistributions in binary form must reproduce the above copyright
! 16: * notice, this list of conditions and the following disclaimer in the
! 17: * documentation and/or other materials provided with the distribution.
! 18: * 3. The names of the copyright holders may not be used to endorse or
! 19: * promote products derived from this software without specific
! 20: * prior written permission.
! 21: *
! 22: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
! 23: * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
! 24: * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
! 25: * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
! 26: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
! 27: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
! 28: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
! 29: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
! 30: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
! 31: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
! 32: *
! 33: * $Id: key.c,v 1.2 2005/04/01 16:47:31 dugsong Exp $
! 34: */
! 35:
! 36: #include <sys/types.h>
! 37: #include <sys/stat.h>
! 38: #include <sys/uio.h>
! 39:
! 40: #include <openssl/ssl.h>
! 41:
! 42: #include <errno.h>
! 43: #include <fcntl.h>
! 44: #include <stdio.h>
! 45: #include <stdlib.h>
! 46: #include <unistd.h>
! 47:
! 48: #include "key.h"
! 49: #include "ssh2.h"
! 50: #include "util.h"
! 51: #include "x509.h"
! 52:
! 53: typedef int (*key_loader)(struct key *, struct iovec *);
! 54:
! 55: static key_loader pubkey_loaders[] = {
! 56: ssh2_load_public,
! 57: x509_load_public,
! 58: NULL
! 59: };
! 60:
! 61: static key_loader privkey_loaders[] = {
! 62: x509_load_private,
! 63: NULL
! 64: };
! 65:
! 66: static int
! 67: load_file(struct iovec *iov, char *filename)
! 68: {
! 69: struct stat st;
! 70: int fd;
! 71:
! 72: if ((fd = open(filename, O_RDONLY)) < 0)
! 73: return (-1);
! 74:
! 75: if (fstat(fd, &st) < 0)
! 76: return (-1);
! 77:
! 78: if (st.st_size == 0) {
! 79: errno = EINVAL;
! 80: return (-1);
! 81: }
! 82: if ((iov->iov_base = malloc(st.st_size + 1)) == NULL)
! 83: return (-1);
! 84:
! 85: iov->iov_len = st.st_size;
! 86: ((u_char *)iov->iov_base)[iov->iov_len] = '\0';
! 87:
! 88: if (read(fd, iov->iov_base, iov->iov_len) != iov->iov_len) {
! 89: free(iov->iov_base);
! 90: return (-1);
! 91: }
! 92: close(fd);
! 93:
! 94: return (0);
! 95: }
! 96:
! 97: struct key *
! 98: key_new(void)
! 99: {
! 100: struct key *k;
! 101:
! 102: if ((k = calloc(sizeof(*k), 1)) == NULL)
! 103: return (NULL);
! 104:
! 105: return (k);
! 106: }
! 107:
! 108: int
! 109: key_load_private(struct key *k, char *filename)
! 110: {
! 111: struct iovec iov;
! 112: int i;
! 113:
! 114: if (load_file(&iov, filename) < 0)
! 115: return (-1);
! 116:
! 117: for (i = 0; privkey_loaders[i] != NULL; i++) {
! 118: if (privkey_loaders[i](k, &iov) == 0)
! 119: return (0);
! 120: }
! 121: return (-1);
! 122: }
! 123:
! 124: int
! 125: key_load_public(struct key *k, char *filename)
! 126: {
! 127: struct iovec iov;
! 128: int i;
! 129:
! 130: if (load_file(&iov, filename) < 0)
! 131: return (-1);
! 132:
! 133: for (i = 0; pubkey_loaders[i] != NULL; i++) {
! 134: if (pubkey_loaders[i](k, &iov) == 0)
! 135: return (0);
! 136: }
! 137: return (-1);
! 138: }
! 139:
! 140: int
! 141: key_sign(struct key *k, u_char *msg, int mlen, u_char *sig, int slen)
! 142: {
! 143: switch (k->type) {
! 144: case KEY_RSA:
! 145: if (RSA_size((RSA *)k->data) > slen) {
! 146: fprintf(stderr, "RSA modulus too large: %d bits\n",
! 147: RSA_size((RSA *)k->data));
! 148: return (-1);
! 149: }
! 150: if (RSA_sign(NID_sha1, msg, mlen, sig, &slen,
! 151: (RSA *)k->data) <= 0) {
! 152: fprintf(stderr, "RSA signing failed\n");
! 153: return (-1);
! 154: }
! 155: break;
! 156:
! 157: case KEY_DSA:
! 158: if (DSA_size((DSA *)k->data) > slen) {
! 159: fprintf(stderr, "DSA signature size too large: "
! 160: "%d bits\n", DSA_size((DSA *)k->data));
! 161: return (-1);
! 162: }
! 163: if (DSA_sign(NID_sha1, msg, mlen, sig, &slen,
! 164: (DSA *)k->data) <= 0) {
! 165: fprintf(stderr, "DSA signing failed\n");
! 166: return (-1);
! 167: }
! 168: break;
! 169:
! 170: default:
! 171: fprintf(stderr, "Unknown key type: %d\n", k->type);
! 172: return (-1);
! 173: }
! 174: return (slen);
! 175: }
! 176:
! 177: int
! 178: key_verify(struct key *k, u_char *msg, int mlen, u_char *sig, int slen)
! 179: {
! 180: switch (k->type) {
! 181:
! 182: case KEY_RSA:
! 183: if (RSA_verify(NID_sha1, msg, mlen,
! 184: sig, slen, (RSA *)k->data) <= 0) {
! 185: fprintf(stderr, "RSA verification failed\n");
! 186: return (-1);
! 187: }
! 188: break;
! 189:
! 190: case KEY_DSA:
! 191: if (DSA_verify(NID_sha1, msg, mlen,
! 192: sig, slen, (DSA *)k->data) <= 0) {
! 193: fprintf(stderr, "DSA verification failed\n");
! 194: return (-1);
! 195: }
! 196: break;
! 197:
! 198: default:
! 199: fprintf(stderr, "Unknown key type: %d\n", k->type);
! 200: return (-1);
! 201: }
! 202: return (slen);
! 203: }
! 204:
! 205: void
! 206: key_free(struct key *k)
! 207: {
! 208: if (k->type == KEY_RSA)
! 209: RSA_free((RSA *)k->data);
! 210: else if (k->type == KEY_DSA)
! 211: DSA_free((DSA *)k->data);
! 212: else if (k->data != NULL)
! 213: free(k->data);
! 214:
! 215: free(k);
! 216: }