comparison signkey.c @ 910:89555751c489 asm

merge up to 2013.63, improve ASM makefile rules a bit
author Matt Johnston <matt@ucc.asn.au>
date Thu, 27 Feb 2014 21:35:58 +0800
parents 30ab30e46452
children 25692c60479e
comparison
equal deleted inserted replaced
909:e4b75744acab 910:89555751c489
25 #include "includes.h" 25 #include "includes.h"
26 #include "dbutil.h" 26 #include "dbutil.h"
27 #include "signkey.h" 27 #include "signkey.h"
28 #include "buffer.h" 28 #include "buffer.h"
29 #include "ssh.h" 29 #include "ssh.h"
30 #include "ecdsa.h"
31
32 static const char *signkey_names[DROPBEAR_SIGNKEY_NUM_NAMED] = {
33 #ifdef DROPBEAR_RSA
34 "ssh-rsa",
35 #endif
36 #ifdef DROPBEAR_DSS
37 "ssh-dss",
38 #endif
39 #ifdef DROPBEAR_ECDSA
40 "ecdsa-sha2-nistp256",
41 "ecdsa-sha2-nistp384",
42 "ecdsa-sha2-nistp521"
43 #endif /* DROPBEAR_ECDSA */
44 };
30 45
31 /* malloc a new sign_key and set the dss and rsa keys to NULL */ 46 /* malloc a new sign_key and set the dss and rsa keys to NULL */
32 sign_key * new_sign_key() { 47 sign_key * new_sign_key() {
33 48
34 sign_key * ret; 49 sign_key * ret;
35 50
36 ret = (sign_key*)m_malloc(sizeof(sign_key)); 51 ret = (sign_key*)m_malloc(sizeof(sign_key));
37 #ifdef DROPBEAR_DSS
38 ret->dsskey = NULL;
39 #endif
40 #ifdef DROPBEAR_RSA
41 ret->rsakey = NULL;
42 #endif
43 ret->filename = NULL;
44 ret->type = DROPBEAR_SIGNKEY_NONE; 52 ret->type = DROPBEAR_SIGNKEY_NONE;
45 ret->source = SIGNKEY_SOURCE_INVALID; 53 ret->source = SIGNKEY_SOURCE_INVALID;
46 return ret; 54 return ret;
47 } 55 }
48 56
49 /* Returns "ssh-dss" or "ssh-rsa" corresponding to the type. Exits fatally 57 /* Returns key name corresponding to the type. Exits fatally
50 * if the type is invalid */ 58 * if the type is invalid */
51 const char* signkey_name_from_type(int type, int *namelen) { 59 const char* signkey_name_from_type(enum signkey_type type, unsigned int *namelen) {
52 60 if (type >= DROPBEAR_SIGNKEY_NUM_NAMED) {
53 #ifdef DROPBEAR_RSA 61 dropbear_exit("Bad key type %d", type);
54 if (type == DROPBEAR_SIGNKEY_RSA) { 62 }
55 *namelen = SSH_SIGNKEY_RSA_LEN; 63
56 return SSH_SIGNKEY_RSA; 64 if (namelen) {
57 } 65 *namelen = strlen(signkey_names[type]);
58 #endif 66 }
59 #ifdef DROPBEAR_DSS 67 return signkey_names[type];
60 if (type == DROPBEAR_SIGNKEY_DSS) { 68 }
61 *namelen = SSH_SIGNKEY_DSS_LEN; 69
62 return SSH_SIGNKEY_DSS; 70 /* Returns DROPBEAR_SIGNKEY_NONE if none match */
63 } 71 enum signkey_type signkey_type_from_name(const char* name, unsigned int namelen) {
64 #endif 72 int i;
65 dropbear_exit("Bad key type %d", type); 73 for (i = 0; i < DROPBEAR_SIGNKEY_NUM_NAMED; i++) {
66 return NULL; /* notreached */ 74 const char *fixed_name = signkey_names[i];
67 } 75 if (namelen == strlen(fixed_name)
68 76 && memcmp(fixed_name, name, namelen) == 0) {
69 /* Returns DROPBEAR_SIGNKEY_RSA, DROPBEAR_SIGNKEY_DSS, 77
70 * or DROPBEAR_SIGNKEY_NONE */ 78 #ifdef DROPBEAR_ECDSA
71 int signkey_type_from_name(const char* name, int namelen) { 79 /* Some of the ECDSA key sizes are defined even if they're not compiled in */
72 80 if (0
73 #ifdef DROPBEAR_RSA 81 #ifndef DROPBEAR_ECC_256
74 if (namelen == SSH_SIGNKEY_RSA_LEN 82 || i == DROPBEAR_SIGNKEY_ECDSA_NISTP256
75 && memcmp(name, SSH_SIGNKEY_RSA, SSH_SIGNKEY_RSA_LEN) == 0) { 83 #endif
76 return DROPBEAR_SIGNKEY_RSA; 84 #ifndef DROPBEAR_ECC_384
77 } 85 || i == DROPBEAR_SIGNKEY_ECDSA_NISTP384
78 #endif 86 #endif
79 #ifdef DROPBEAR_DSS 87 #ifndef DROPBEAR_ECC_521
80 if (namelen == SSH_SIGNKEY_DSS_LEN 88 || i == DROPBEAR_SIGNKEY_ECDSA_NISTP521
81 && memcmp(name, SSH_SIGNKEY_DSS, SSH_SIGNKEY_DSS_LEN) == 0) { 89 #endif
82 return DROPBEAR_SIGNKEY_DSS; 90 ) {
83 } 91 TRACE(("attempt to use ecdsa type %d not compiled in", i))
84 #endif 92 return DROPBEAR_SIGNKEY_NONE;
93 }
94 #endif
95
96 return i;
97 }
98 }
85 99
86 TRACE(("signkey_type_from_name unexpected key type.")) 100 TRACE(("signkey_type_from_name unexpected key type."))
87 101
88 return DROPBEAR_SIGNKEY_NONE; 102 return DROPBEAR_SIGNKEY_NONE;
103 }
104
105 /* Returns a pointer to the key part specific to "type" */
106 void **
107 signkey_key_ptr(sign_key *key, enum signkey_type type) {
108 switch (type) {
109 #ifdef DROPBEAR_ECC_256
110 case DROPBEAR_SIGNKEY_ECDSA_NISTP256:
111 return (void**)&key->ecckey256;
112 #endif
113 #ifdef DROPBEAR_ECC_384
114 case DROPBEAR_SIGNKEY_ECDSA_NISTP384:
115 return (void**)&key->ecckey384;
116 #endif
117 #ifdef DROPBEAR_ECC_521
118 case DROPBEAR_SIGNKEY_ECDSA_NISTP521:
119 return (void**)&key->ecckey521;
120 #endif
121 #ifdef DROPBEAR_RSA
122 case DROPBEAR_SIGNKEY_RSA:
123 return (void**)&key->rsakey;
124 #endif
125 #ifdef DROPBEAR_DSS
126 case DROPBEAR_SIGNKEY_DSS:
127 return (void**)&key->dsskey;
128 #endif
129 default:
130 return NULL;
131 }
89 } 132 }
90 133
91 /* returns DROPBEAR_SUCCESS on success, DROPBEAR_FAILURE on fail. 134 /* returns DROPBEAR_SUCCESS on success, DROPBEAR_FAILURE on fail.
92 * type should be set by the caller to specify the type to read, and 135 * type should be set by the caller to specify the type to read, and
93 * on return is set to the type read (useful when type = _ANY) */ 136 * on return is set to the type read (useful when type = _ANY) */
94 int buf_get_pub_key(buffer *buf, sign_key *key, int *type) { 137 int buf_get_pub_key(buffer *buf, sign_key *key, enum signkey_type *type) {
95 138
96 unsigned char* ident; 139 unsigned char* ident;
97 unsigned int len; 140 unsigned int len;
98 int keytype; 141 int keytype;
99 int ret = DROPBEAR_FAILURE; 142 int ret = DROPBEAR_FAILURE;
134 if (ret == DROPBEAR_FAILURE) { 177 if (ret == DROPBEAR_FAILURE) {
135 m_free(key->rsakey); 178 m_free(key->rsakey);
136 } 179 }
137 } 180 }
138 #endif 181 #endif
182 #ifdef DROPBEAR_ECDSA
183 if (signkey_is_ecdsa(keytype)) {
184 ecc_key **eck = (ecc_key**)signkey_key_ptr(key, keytype);
185 if (eck) {
186 if (*eck) {
187 ecc_free(*eck);
188 *eck = NULL;
189 }
190 *eck = buf_get_ecdsa_pub_key(buf);
191 if (*eck) {
192 ret = DROPBEAR_SUCCESS;
193 }
194 }
195 }
196 #endif
139 197
140 TRACE2(("leave buf_get_pub_key")) 198 TRACE2(("leave buf_get_pub_key"))
141 199
142 return ret; 200 return ret;
143 201
144 } 202 }
145 203
146 /* returns DROPBEAR_SUCCESS on success, DROPBEAR_FAILURE on fail. 204 /* returns DROPBEAR_SUCCESS on success, DROPBEAR_FAILURE on fail.
147 * type should be set by the caller to specify the type to read, and 205 * type should be set by the caller to specify the type to read, and
148 * on return is set to the type read (useful when type = _ANY) */ 206 * on return is set to the type read (useful when type = _ANY) */
149 int buf_get_priv_key(buffer *buf, sign_key *key, int *type) { 207 int buf_get_priv_key(buffer *buf, sign_key *key, enum signkey_type *type) {
150 208
151 unsigned char* ident; 209 unsigned char* ident;
152 unsigned int len; 210 unsigned int len;
153 int keytype; 211 int keytype;
154 int ret = DROPBEAR_FAILURE; 212 int ret = DROPBEAR_FAILURE;
187 if (ret == DROPBEAR_FAILURE) { 245 if (ret == DROPBEAR_FAILURE) {
188 m_free(key->rsakey); 246 m_free(key->rsakey);
189 } 247 }
190 } 248 }
191 #endif 249 #endif
250 #ifdef DROPBEAR_ECDSA
251 if (signkey_is_ecdsa(keytype)) {
252 ecc_key **eck = (ecc_key**)signkey_key_ptr(key, keytype);
253 if (eck) {
254 if (*eck) {
255 ecc_free(*eck);
256 *eck = NULL;
257 }
258 *eck = buf_get_ecdsa_priv_key(buf);
259 if (*eck) {
260 ret = DROPBEAR_SUCCESS;
261 }
262 }
263 }
264 #endif
192 265
193 TRACE2(("leave buf_get_priv_key")) 266 TRACE2(("leave buf_get_priv_key"))
194 267
195 return ret; 268 return ret;
196 269
197 } 270 }
198 271
199 /* type is either DROPBEAR_SIGNKEY_DSS or DROPBEAR_SIGNKEY_RSA */ 272 /* type is either DROPBEAR_SIGNKEY_DSS or DROPBEAR_SIGNKEY_RSA */
200 void buf_put_pub_key(buffer* buf, sign_key *key, int type) { 273 void buf_put_pub_key(buffer* buf, sign_key *key, enum signkey_type type) {
201 274
202 buffer *pubkeys; 275 buffer *pubkeys;
203 276
204 TRACE2(("enter buf_put_pub_key")) 277 TRACE2(("enter buf_put_pub_key"))
205 pubkeys = buf_new(MAX_PUBKEY_SIZE); 278 pubkeys = buf_new(MAX_PUBKEY_SIZE);
212 #ifdef DROPBEAR_RSA 285 #ifdef DROPBEAR_RSA
213 if (type == DROPBEAR_SIGNKEY_RSA) { 286 if (type == DROPBEAR_SIGNKEY_RSA) {
214 buf_put_rsa_pub_key(pubkeys, key->rsakey); 287 buf_put_rsa_pub_key(pubkeys, key->rsakey);
215 } 288 }
216 #endif 289 #endif
290 #ifdef DROPBEAR_ECDSA
291 if (signkey_is_ecdsa(type)) {
292 ecc_key **eck = (ecc_key**)signkey_key_ptr(key, type);
293 if (eck) {
294 buf_put_ecdsa_pub_key(pubkeys, *eck);
295 }
296 }
297 #endif
217 if (pubkeys->len == 0) { 298 if (pubkeys->len == 0) {
218 dropbear_exit("Bad key types in buf_put_pub_key"); 299 dropbear_exit("Bad key types in buf_put_pub_key");
219 } 300 }
220 301
221 buf_setpos(pubkeys, 0); 302 buf_putbufstring(buf, pubkeys);
222 buf_putstring(buf, buf_getptr(pubkeys, pubkeys->len),
223 pubkeys->len);
224
225 buf_free(pubkeys); 303 buf_free(pubkeys);
226 TRACE2(("leave buf_put_pub_key")) 304 TRACE2(("leave buf_put_pub_key"))
227 } 305 }
228 306
229 /* type is either DROPBEAR_SIGNKEY_DSS or DROPBEAR_SIGNKEY_RSA */ 307 /* type is either DROPBEAR_SIGNKEY_DSS or DROPBEAR_SIGNKEY_RSA */
230 void buf_put_priv_key(buffer* buf, sign_key *key, int type) { 308 void buf_put_priv_key(buffer* buf, sign_key *key, enum signkey_type type) {
231 309
232 TRACE(("enter buf_put_priv_key")) 310 TRACE(("enter buf_put_priv_key"))
233 TRACE(("type is %d", type)) 311 TRACE(("type is %d", type))
234 312
235 #ifdef DROPBEAR_DSS 313 #ifdef DROPBEAR_DSS
244 buf_put_rsa_priv_key(buf, key->rsakey); 322 buf_put_rsa_priv_key(buf, key->rsakey);
245 TRACE(("leave buf_put_priv_key: rsa done")) 323 TRACE(("leave buf_put_priv_key: rsa done"))
246 return; 324 return;
247 } 325 }
248 #endif 326 #endif
327 #ifdef DROPBEAR_ECDSA
328 if (signkey_is_ecdsa(type)) {
329 ecc_key **eck = (ecc_key**)signkey_key_ptr(key, type);
330 if (eck) {
331 buf_put_ecdsa_priv_key(buf, *eck);
332 TRACE(("leave buf_put_priv_key: ecdsa done"))
333 return;
334 }
335 }
336 #endif
249 dropbear_exit("Bad key types in put pub key"); 337 dropbear_exit("Bad key types in put pub key");
250 } 338 }
251 339
252 void sign_key_free(sign_key *key) { 340 void sign_key_free(sign_key *key) {
253 341
259 #endif 347 #endif
260 #ifdef DROPBEAR_RSA 348 #ifdef DROPBEAR_RSA
261 rsa_key_free(key->rsakey); 349 rsa_key_free(key->rsakey);
262 key->rsakey = NULL; 350 key->rsakey = NULL;
263 #endif 351 #endif
352 #ifdef DROPBEAR_ECDSA
353 #ifdef DROPBEAR_ECC_256
354 if (key->ecckey256) {
355 ecc_free(key->ecckey256);
356 key->ecckey256 = NULL;
357 }
358 #endif
359 #ifdef DROPBEAR_ECC_384
360 if (key->ecckey384) {
361 ecc_free(key->ecckey384);
362 key->ecckey384 = NULL;
363 }
364 #endif
365 #ifdef DROPBEAR_ECC_521
366 if (key->ecckey521) {
367 ecc_free(key->ecckey521);
368 key->ecckey521 = NULL;
369 }
370 #endif
371 #endif
264 372
265 m_free(key->filename); 373 m_free(key->filename);
266 374
267 m_free(key); 375 m_free(key);
268 TRACE2(("leave sign_key_free")) 376 TRACE2(("leave sign_key_free"))
269 } 377 }
270 378
271 static char hexdig(unsigned char x) { 379 static char hexdig(unsigned char x) {
272
273 if (x > 0xf) 380 if (x > 0xf)
274 return 'X'; 381 return 'X';
275 382
276 if (x < 10) 383 if (x < 10)
277 return '0' + x; 384 return '0' + x;
331 /* skip the size int of the string - this is a bit messy */ 438 /* skip the size int of the string - this is a bit messy */
332 sha1_process(&hs, keyblob, keybloblen); 439 sha1_process(&hs, keyblob, keybloblen);
333 440
334 sha1_done(&hs, hash); 441 sha1_done(&hs, hash);
335 442
336 /* "sha1 hexfingerprinthere\0", each hex digit is "AB:" etc */ 443 /* "sha1!! hexfingerprinthere\0", each hex digit is "AB:" etc */
337 buflen = 5 + 3*SHA1_HASH_SIZE; 444 buflen = 7 + 3*SHA1_HASH_SIZE;
338 ret = (char*)m_malloc(buflen); 445 ret = (char*)m_malloc(buflen);
339 446
340 strcpy(ret, "sha1 "); 447 strcpy(ret, "sha1!! ");
341 448
342 for (i = 0; i < SHA1_HASH_SIZE; i++) { 449 for (i = 0; i < SHA1_HASH_SIZE; i++) {
343 unsigned int pos = 5 + 3*i; 450 unsigned int pos = 7 + 3*i;
344 ret[pos] = hexdig(hash[i] >> 4); 451 ret[pos] = hexdig(hash[i] >> 4);
345 ret[pos+1] = hexdig(hash[i] & 0x0f); 452 ret[pos+1] = hexdig(hash[i] & 0x0f);
346 ret[pos+2] = ':'; 453 ret[pos+2] = ':';
347 } 454 }
348 ret[buflen-1] = 0x0; 455 ret[buflen-1] = 0x0;
361 #else 468 #else
362 return sign_key_sha1_fingerprint(keyblob, keybloblen); 469 return sign_key_sha1_fingerprint(keyblob, keybloblen);
363 #endif 470 #endif
364 } 471 }
365 472
366 void buf_put_sign(buffer* buf, sign_key *key, int type, 473 void buf_put_sign(buffer* buf, sign_key *key, enum signkey_type type,
367 const unsigned char *data, unsigned int len) { 474 buffer *data_buf) {
368
369 buffer *sigblob; 475 buffer *sigblob;
370 sigblob = buf_new(MAX_PUBKEY_SIZE); 476 sigblob = buf_new(MAX_PUBKEY_SIZE);
371 477
372 #ifdef DROPBEAR_DSS 478 #ifdef DROPBEAR_DSS
373 if (type == DROPBEAR_SIGNKEY_DSS) { 479 if (type == DROPBEAR_SIGNKEY_DSS) {
374 buf_put_dss_sign(sigblob, key->dsskey, data, len); 480 buf_put_dss_sign(sigblob, key->dsskey, data_buf);
375 } 481 }
376 #endif 482 #endif
377 #ifdef DROPBEAR_RSA 483 #ifdef DROPBEAR_RSA
378 if (type == DROPBEAR_SIGNKEY_RSA) { 484 if (type == DROPBEAR_SIGNKEY_RSA) {
379 buf_put_rsa_sign(sigblob, key->rsakey, data, len); 485 buf_put_rsa_sign(sigblob, key->rsakey, data_buf);
486 }
487 #endif
488 #ifdef DROPBEAR_ECDSA
489 if (signkey_is_ecdsa(type)) {
490 ecc_key **eck = (ecc_key**)signkey_key_ptr(key, type);
491 if (eck) {
492 buf_put_ecdsa_sign(sigblob, *eck, data_buf);
493 }
380 } 494 }
381 #endif 495 #endif
382 if (sigblob->len == 0) { 496 if (sigblob->len == 0) {
383 dropbear_exit("Non-matching signing type"); 497 dropbear_exit("Non-matching signing type");
384 } 498 }
385 buf_setpos(sigblob, 0); 499 buf_putbufstring(buf, sigblob);
386 buf_putstring(buf, buf_getptr(sigblob, sigblob->len),
387 sigblob->len);
388
389 buf_free(sigblob); 500 buf_free(sigblob);
390 501
391 } 502 }
392 503
393 #ifdef DROPBEAR_SIGNKEY_VERIFY 504 #ifdef DROPBEAR_SIGNKEY_VERIFY
394 /* Return DROPBEAR_SUCCESS or DROPBEAR_FAILURE. 505 /* Return DROPBEAR_SUCCESS or DROPBEAR_FAILURE.
395 * If FAILURE is returned, the position of 506 * If FAILURE is returned, the position of
396 * buf is undefined. If SUCCESS is returned, buf will be positioned after the 507 * buf is undefined. If SUCCESS is returned, buf will be positioned after the
397 * signature blob */ 508 * signature blob */
398 int buf_verify(buffer * buf, sign_key *key, const unsigned char *data, 509 int buf_verify(buffer * buf, sign_key *key, buffer *data_buf) {
399 unsigned int len) {
400 510
401 unsigned int bloblen; 511 unsigned char * type_name = NULL;
402 unsigned char * ident = NULL; 512 unsigned int type_name_len = 0;
403 unsigned int identlen = 0; 513 enum signkey_type type;
404 514
405 TRACE(("enter buf_verify")) 515 TRACE(("enter buf_verify"))
406 516
407 bloblen = buf_getint(buf); 517 buf_getint(buf); /* blob length */
408 ident = buf_getstring(buf, &identlen); 518 type_name = buf_getstring(buf, &type_name_len);
409 519 type = signkey_type_from_name(type_name, type_name_len);
410 #ifdef DROPBEAR_DSS 520 m_free(type_name);
411 if (bloblen == DSS_SIGNATURE_SIZE && 521
412 memcmp(ident, SSH_SIGNKEY_DSS, identlen) == 0) { 522 #ifdef DROPBEAR_DSS
413 m_free(ident); 523 if (type == DROPBEAR_SIGNKEY_DSS) {
414 if (key->dsskey == NULL) { 524 if (key->dsskey == NULL) {
415 dropbear_exit("No DSS key to verify signature"); 525 dropbear_exit("No DSS key to verify signature");
416 } 526 }
417 return buf_dss_verify(buf, key->dsskey, data, len); 527 return buf_dss_verify(buf, key->dsskey, data_buf);
418 } 528 }
419 #endif 529 #endif
420 530
421 #ifdef DROPBEAR_RSA 531 #ifdef DROPBEAR_RSA
422 if (memcmp(ident, SSH_SIGNKEY_RSA, identlen) == 0) { 532 if (type == DROPBEAR_SIGNKEY_RSA) {
423 m_free(ident);
424 if (key->rsakey == NULL) { 533 if (key->rsakey == NULL) {
425 dropbear_exit("No RSA key to verify signature"); 534 dropbear_exit("No RSA key to verify signature");
426 } 535 }
427 return buf_rsa_verify(buf, key->rsakey, data, len); 536 return buf_rsa_verify(buf, key->rsakey, data_buf);
428 } 537 }
429 #endif 538 #endif
430 539 #ifdef DROPBEAR_ECDSA
431 m_free(ident); 540 if (signkey_is_ecdsa(type)) {
541 ecc_key **eck = (ecc_key**)signkey_key_ptr(key, type);
542 if (eck) {
543 return buf_ecdsa_verify(buf, *eck, data_buf);
544 }
545 }
546 #endif
547
432 dropbear_exit("Non-matching signing type"); 548 dropbear_exit("Non-matching signing type");
433 return DROPBEAR_FAILURE; 549 return DROPBEAR_FAILURE;
434 } 550 }
435 #endif /* DROPBEAR_SIGNKEY_VERIFY */ 551 #endif /* DROPBEAR_SIGNKEY_VERIFY */
436 552