Mercurial > dropbear
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 } |