comparison dropbearkey.c @ 4:fe6bca95afa7

Makefile.in contains updated files required
author Matt Johnston <matt@ucc.asn.au>
date Tue, 01 Jun 2004 02:46:09 +0000
parents
children 223b0f5f8dce
comparison
equal deleted inserted replaced
-1:000000000000 4:fe6bca95afa7
1 /*
2 * Dropbear - a SSH2 server
3 *
4 * Copyright (c) 2002,2003 Matt Johnston
5 * All rights reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE. */
24
25 /* The format of the keyfiles is basically a raw dump of the buffer. Data types
26 * are specified in the transport draft - string is a 32-bit len then the
27 * non-null-terminated string, mp_int is a 32-bit len then the bignum data.
28 * The actual functions are buf_put_rsa_priv_key() and buf_put_dss_priv_key()
29
30 * RSA:
31 * string "ssh-rsa"
32 * mp_int e
33 * mp_int n
34 * mp_int d
35 * mp_int p (newer versions only)
36 * mp_int q (newer versions only)
37 *
38 * DSS:
39 * string "ssh-dss"
40 * mp_int p
41 * mp_int q
42 * mp_int g
43 * mp_int y
44 * mp_int x
45 *
46 */
47 #include "includes.h"
48 #include "runopts.h"
49 #include "signkey.h"
50 #include "buffer.h"
51 #include "dbutil.h"
52
53 #include "genrsa.h"
54 #include "gendss.h"
55
56 static void printhelp(char * progname);
57
58 #define BUF_SIZE 2000
59
60 #define RSA_SIZE (1024/8) /* 1024 bit */
61 #define DSS_SIZE (1024/8) /* 1024 bit */
62
63 static void buf_writefile(buffer * buf, const char * filename);
64
65 /* Print a help message */
66 static void printhelp(char * progname) {
67
68 fprintf(stderr, "Usage: %s -t <type> -f <filename> [-s bits]\n"
69 "Options are:\n"
70 "-t type Type of key to generate. One of:\n"
71 #ifdef DROPBEAR_RSA
72 " rsa\n"
73 #endif
74 #ifdef DROPBEAR_DSS
75 " dss\n"
76 #endif
77 "-f filename Use filename for the secret key\n"
78 "-s bits Key size in bits, should be "
79 "multiple of 8 (optional)\n",
80 progname);
81 }
82
83 #if defined(DBMULTI_KEY) || !defined(DROPBEAR_MULTI)
84 #if defined(DBMULTI_KEY) && defined(DROPBEAR_MULTI)
85 int dropbearkey_main(int argc, char ** argv) {
86 #else
87 int main(int argc, char ** argv) {
88 #endif
89
90 int i;
91 char ** next = 0;
92 sign_key *key;
93 buffer *buf;
94 char * filename = NULL;
95 int keytype = -1;
96 char * typetext = NULL;
97 char * sizetext = NULL;
98 unsigned int bits;
99 unsigned int keysize;
100
101 /* get the commandline options */
102 for (i = 1; i < argc; i++) {
103 if (next) {
104 *next = argv[i];
105 if (*next == NULL) {
106 fprintf(stderr, "Invalid null argument");
107 }
108 next = 0x00;
109 continue;
110 }
111
112 if (argv[i][0] == '-') {
113 switch (argv[i][1]) {
114 case 'f':
115 next = &filename;
116 break;
117 case 't':
118 next = &typetext;
119 break;
120 case 's':
121 next = &sizetext;
122 break;
123 case 'h':
124 printhelp(argv[0]);
125 exit(EXIT_SUCCESS);
126 break;
127 default:
128 fprintf(stderr, "Unknown argument %s\n", argv[i]);
129 printhelp(argv[0]);
130 exit(EXIT_FAILURE);
131 break;
132 }
133 }
134 }
135
136 /* check/parse args */
137 if (!typetext) {
138 fprintf(stderr, "Must specify file type, one of:\n"
139 #ifdef DROPBEAR_RSA
140 "rsa\n"
141 #endif
142 #ifdef DROPBEAR_DSS
143 "dss\n"
144 #endif
145 "\n"
146 );
147 printhelp(argv[0]);
148 exit(EXIT_FAILURE);
149 }
150
151 if (strlen(typetext) == 3) {
152 #ifdef DROPBEAR_RSA
153 if (strncmp(typetext, "rsa", 3) == 0) {
154 keytype = DROPBEAR_SIGNKEY_RSA;
155 TRACE(("type is rsa"));
156 }
157 #endif
158 #ifdef DROPBEAR_DSS
159 if (strncmp(typetext, "dss", 3) == 0) {
160 keytype = DROPBEAR_SIGNKEY_DSS;
161 TRACE(("type is dss"));
162 }
163 #endif
164 }
165 if (keytype == -1) {
166 fprintf(stderr, "Unknown key type '%s'\n", typetext);
167 printhelp(argv[0]);
168 exit(EXIT_FAILURE);
169 }
170
171 if (sizetext) {
172 if (sscanf(sizetext, "%u", &bits) != 1) {
173 fprintf(stderr, "Bits must be an integer\n");
174 exit(EXIT_FAILURE);
175 }
176
177 if (bits < 512 || bits > 4096 || (bits % 8 != 0)) {
178 fprintf(stderr, "Bits must satisfy 512 <= bits <= 4096, and be a"
179 " multiple of 8\n");
180 exit(EXIT_FAILURE);
181 }
182
183 keysize = bits / 8;
184 } else {
185 if (keytype == DROPBEAR_SIGNKEY_DSS) {
186 keysize = DSS_SIZE;
187 } else if (keytype == DROPBEAR_SIGNKEY_RSA) {
188 keysize = RSA_SIZE;
189 } else {
190 exit(EXIT_FAILURE); /* not reached */
191 }
192 }
193
194 if (!filename) {
195 fprintf(stderr, "Must specify a key filename\n");
196 printhelp(argv[0]);
197 exit(EXIT_FAILURE);
198 }
199
200 fprintf(stderr, "Will output %d bit %s secret key to '%s'\n", keysize*8,
201 typetext, filename);
202
203 /* don't want the file readable by others */
204 umask(077);
205
206 /* now we can generate the key */
207 key = new_sign_key();
208
209 fprintf(stderr, "Generating key, this may take a while...\n");
210 switch(keytype) {
211 #ifdef DROPBEAR_RSA
212 case DROPBEAR_SIGNKEY_RSA:
213 key->rsakey = gen_rsa_priv_key(keysize); /* 128 bytes = 1024 bit */
214 break;
215 #endif
216 #ifdef DROPBEAR_DSS
217 case DROPBEAR_SIGNKEY_DSS:
218 key->dsskey = gen_dss_priv_key(keysize); /* 128 bytes = 1024 bit */
219 break;
220 #endif
221 default:
222 fprintf(stderr, "Internal error, bad key type\n");
223 exit(EXIT_FAILURE);
224 }
225
226 buf = buf_new(BUF_SIZE);
227
228 buf_put_priv_key(buf, key, keytype);
229 buf_setpos(buf, 0);
230 buf_writefile(buf, filename);
231
232 buf_burn(buf);
233 buf_free(buf);
234 sign_key_free(key);
235
236 fprintf(stderr, "Done.\n");
237
238 return EXIT_SUCCESS;
239 }
240 #endif
241
242 /* Write a buffer to a file specified, failing if the file exists */
243 static void buf_writefile(buffer * buf, const char * filename) {
244
245 int fd;
246 int len;
247
248 fd = open(filename, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
249 if (fd < 0) {
250 fprintf(stderr, "Couldn't create new file %s\n", filename);
251 perror("Reason");
252 buf_burn(buf);
253 exit(EXIT_FAILURE);
254 }
255
256 /* write the file now */
257 while (buf->pos != buf->len) {
258 len = write(fd, buf_getptr(buf, buf->len - buf->pos),
259 buf->len - buf->pos);
260 if (errno == EINTR) {
261 continue;
262 }
263 if (len <= 0) {
264 fprintf(stderr, "Failed writing file '%s'\n",filename);
265 perror("Reason");
266 exit(EXIT_FAILURE);
267 }
268 buf_incrpos(buf, len);
269 }
270
271 close(fd);
272 }