Annotation of src/usr.bin/gzsig/key.c, Revision 1.1.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: }