Annotation of src/usr.bin/gzsig/key.c, Revision 1.4
1.4 ! otto 1: /* $OpenBSD: key.c,v 1.3 2005/05/29 02:41:42 marius 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: {
104: struct key *k;
105:
106: if ((k = calloc(sizeof(*k), 1)) == NULL)
107: return (NULL);
108:
109: return (k);
110: }
111:
112: int
113: key_load_private(struct key *k, char *filename)
114: {
115: struct iovec iov;
116: int i;
117:
118: if (load_file(&iov, filename) < 0)
119: return (-1);
120:
121: for (i = 0; privkey_loaders[i] != NULL; i++) {
122: if (privkey_loaders[i](k, &iov) == 0)
123: return (0);
124: }
125: return (-1);
126: }
127:
128: int
129: key_load_public(struct key *k, char *filename)
130: {
131: struct iovec iov;
132: int i;
133:
134: if (load_file(&iov, filename) < 0)
135: return (-1);
136:
137: for (i = 0; pubkey_loaders[i] != NULL; i++) {
138: if (pubkey_loaders[i](k, &iov) == 0)
139: return (0);
140: }
141: return (-1);
142: }
143:
144: int
145: key_sign(struct key *k, u_char *msg, int mlen, u_char *sig, int slen)
146: {
147: switch (k->type) {
148: case KEY_RSA:
149: if (RSA_size((RSA *)k->data) > slen) {
150: fprintf(stderr, "RSA modulus too large: %d bits\n",
151: RSA_size((RSA *)k->data));
152: return (-1);
153: }
154: if (RSA_sign(NID_sha1, msg, mlen, sig, &slen,
155: (RSA *)k->data) <= 0) {
156: fprintf(stderr, "RSA signing failed\n");
157: return (-1);
158: }
159: break;
160:
161: case KEY_DSA:
162: if (DSA_size((DSA *)k->data) > slen) {
163: fprintf(stderr, "DSA signature size too large: "
164: "%d bits\n", DSA_size((DSA *)k->data));
165: return (-1);
166: }
167: if (DSA_sign(NID_sha1, msg, mlen, sig, &slen,
168: (DSA *)k->data) <= 0) {
169: fprintf(stderr, "DSA signing failed\n");
170: return (-1);
171: }
172: break;
173:
174: default:
175: fprintf(stderr, "Unknown key type: %d\n", k->type);
176: return (-1);
177: }
178: return (slen);
179: }
180:
181: int
182: key_verify(struct key *k, u_char *msg, int mlen, u_char *sig, int slen)
183: {
184: switch (k->type) {
185:
186: case KEY_RSA:
187: if (RSA_verify(NID_sha1, msg, mlen,
188: sig, slen, (RSA *)k->data) <= 0) {
189: fprintf(stderr, "RSA verification failed\n");
190: return (-1);
191: }
192: break;
193:
194: case KEY_DSA:
195: if (DSA_verify(NID_sha1, msg, mlen,
196: sig, slen, (DSA *)k->data) <= 0) {
197: fprintf(stderr, "DSA verification failed\n");
198: return (-1);
199: }
200: break;
201:
202: default:
203: fprintf(stderr, "Unknown key type: %d\n", k->type);
204: return (-1);
205: }
206: return (slen);
207: }
208:
209: void
210: key_free(struct key *k)
211: {
212: if (k->type == KEY_RSA)
213: RSA_free((RSA *)k->data);
214: else if (k->type == KEY_DSA)
215: DSA_free((DSA *)k->data);
216: else if (k->data != NULL)
217: free(k->data);
218:
219: free(k);
220: }