Annotation of src/usr.bin/gzsig/key.c, Revision 1.5
1.5 ! djm 1: /* $OpenBSD: key.c,v 1.4 2006/04/01 19:57:32 otto Exp $ */
1.1 marius 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: *
1.2 marius 33: * $Vendor: key.c,v 1.2 2005/04/01 16:47:31 dugsong Exp $
1.1 marius 34: */
35:
1.4 otto 36: #include <sys/limits.h>
1.1 marius 37: #include <sys/types.h>
38: #include <sys/stat.h>
39: #include <sys/uio.h>
40:
41: #include <openssl/ssl.h>
42:
43: #include <errno.h>
44: #include <fcntl.h>
45: #include <stdio.h>
46: #include <stdlib.h>
47: #include <unistd.h>
48:
49: #include "key.h"
1.3 marius 50: #include "ssh.h"
1.1 marius 51: #include "ssh2.h"
52: #include "util.h"
53: #include "x509.h"
54:
55: typedef int (*key_loader)(struct key *, struct iovec *);
56:
57: static key_loader pubkey_loaders[] = {
1.3 marius 58: ssh_load_public,
1.1 marius 59: ssh2_load_public,
60: x509_load_public,
61: NULL
62: };
63:
64: static key_loader privkey_loaders[] = {
1.3 marius 65: ssh_load_private,
1.1 marius 66: x509_load_private,
67: NULL
68: };
69:
70: static int
71: load_file(struct iovec *iov, char *filename)
72: {
73: struct stat st;
74: int fd;
75:
76: if ((fd = open(filename, O_RDONLY)) < 0)
77: return (-1);
78:
79: if (fstat(fd, &st) < 0)
80: return (-1);
81:
1.4 otto 82: if (st.st_size == 0 || st.st_size >= SIZE_MAX) {
1.1 marius 83: errno = EINVAL;
84: return (-1);
85: }
86: if ((iov->iov_base = malloc(st.st_size + 1)) == NULL)
87: return (-1);
88:
89: iov->iov_len = st.st_size;
90: ((u_char *)iov->iov_base)[iov->iov_len] = '\0';
91:
92: if (read(fd, iov->iov_base, iov->iov_len) != iov->iov_len) {
93: free(iov->iov_base);
94: return (-1);
95: }
96: close(fd);
97:
98: return (0);
99: }
100:
101: struct key *
102: key_new(void)
103: {
1.5 ! djm 104: return (calloc(1, sizeof(struct key)));
1.1 marius 105: }
106:
107: int
108: key_load_private(struct key *k, char *filename)
109: {
110: struct iovec iov;
111: int i;
112:
113: if (load_file(&iov, filename) < 0)
114: return (-1);
115:
116: for (i = 0; privkey_loaders[i] != NULL; i++) {
117: if (privkey_loaders[i](k, &iov) == 0)
118: return (0);
119: }
120: return (-1);
121: }
122:
123: int
124: key_load_public(struct key *k, char *filename)
125: {
126: struct iovec iov;
127: int i;
128:
129: if (load_file(&iov, filename) < 0)
130: return (-1);
131:
132: for (i = 0; pubkey_loaders[i] != NULL; i++) {
133: if (pubkey_loaders[i](k, &iov) == 0)
134: return (0);
135: }
136: return (-1);
137: }
138:
139: int
140: key_sign(struct key *k, u_char *msg, int mlen, u_char *sig, int slen)
141: {
142: switch (k->type) {
143: case KEY_RSA:
144: if (RSA_size((RSA *)k->data) > slen) {
145: fprintf(stderr, "RSA modulus too large: %d bits\n",
146: RSA_size((RSA *)k->data));
147: return (-1);
148: }
149: if (RSA_sign(NID_sha1, msg, mlen, sig, &slen,
150: (RSA *)k->data) <= 0) {
151: fprintf(stderr, "RSA signing failed\n");
152: return (-1);
153: }
154: break;
155:
156: case KEY_DSA:
157: if (DSA_size((DSA *)k->data) > slen) {
158: fprintf(stderr, "DSA signature size too large: "
159: "%d bits\n", DSA_size((DSA *)k->data));
160: return (-1);
161: }
162: if (DSA_sign(NID_sha1, msg, mlen, sig, &slen,
163: (DSA *)k->data) <= 0) {
164: fprintf(stderr, "DSA signing failed\n");
165: return (-1);
166: }
167: break;
168:
169: default:
170: fprintf(stderr, "Unknown key type: %d\n", k->type);
171: return (-1);
172: }
173: return (slen);
174: }
175:
176: int
177: key_verify(struct key *k, u_char *msg, int mlen, u_char *sig, int slen)
178: {
179: switch (k->type) {
180:
181: case KEY_RSA:
182: if (RSA_verify(NID_sha1, msg, mlen,
183: sig, slen, (RSA *)k->data) <= 0) {
184: fprintf(stderr, "RSA verification failed\n");
185: return (-1);
186: }
187: break;
188:
189: case KEY_DSA:
190: if (DSA_verify(NID_sha1, msg, mlen,
191: sig, slen, (DSA *)k->data) <= 0) {
192: fprintf(stderr, "DSA verification failed\n");
193: return (-1);
194: }
195: break;
196:
197: default:
198: fprintf(stderr, "Unknown key type: %d\n", k->type);
199: return (-1);
200: }
201: return (slen);
202: }
203:
204: void
205: key_free(struct key *k)
206: {
207: if (k->type == KEY_RSA)
208: RSA_free((RSA *)k->data);
209: else if (k->type == KEY_DSA)
210: DSA_free((DSA *)k->data);
211: else if (k->data != NULL)
212: free(k->data);
213:
214: free(k);
215: }