Mercurial > dropbear
comparison signkey.c @ 794:d386defb5376 ecc
more ecdsa signkey work, not correct
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sun, 28 Apr 2013 23:17:43 +0800 |
parents | 70625eed40c9 |
children | 7f604f9b3756 |
comparison
equal
deleted
inserted
replaced
793:70625eed40c9 | 794:d386defb5376 |
---|---|
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 #ifdef DROPBEAR_ECC_256 | |
41 "ecdsa-sha2-nistp256", | |
42 #endif | |
43 #ifdef DROPBEAR_ECC_384 | |
44 "ecdsa-sha2-nistp384", | |
45 #endif | |
46 #ifdef DROPBEAR_ECC_521 | |
47 "ecdsa-sha2-nistp521", | |
48 #endif | |
49 "ecdsa" // for keygen | |
50 #endif // DROPBEAR_ECDSA | |
51 }; | |
30 | 52 |
31 /* malloc a new sign_key and set the dss and rsa keys to NULL */ | 53 /* malloc a new sign_key and set the dss and rsa keys to NULL */ |
32 sign_key * new_sign_key() { | 54 sign_key * new_sign_key() { |
33 | 55 |
34 sign_key * ret; | 56 sign_key * ret; |
37 ret->type = DROPBEAR_SIGNKEY_NONE; | 59 ret->type = DROPBEAR_SIGNKEY_NONE; |
38 ret->source = SIGNKEY_SOURCE_INVALID; | 60 ret->source = SIGNKEY_SOURCE_INVALID; |
39 return ret; | 61 return ret; |
40 } | 62 } |
41 | 63 |
42 /* Returns "ssh-dss" or "ssh-rsa" corresponding to the type. Exits fatally | 64 /* Returns key name corresponding to the type. Exits fatally |
43 * if the type is invalid */ | 65 * if the type is invalid */ |
44 const char* signkey_name_from_type(int type, int *namelen) { | 66 const char* signkey_name_from_type(enum signkey_type type, unsigned int *namelen) { |
45 | 67 if (type >= DROPBEAR_SIGNKEY_NUM_NAMED) { |
46 #ifdef DROPBEAR_RSA | 68 dropbear_exit("Bad key type %d", type); |
47 if (type == DROPBEAR_SIGNKEY_RSA) { | 69 } |
48 *namelen = SSH_SIGNKEY_RSA_LEN; | 70 |
49 return SSH_SIGNKEY_RSA; | 71 if (namelen) { |
50 } | 72 *namelen = strlen(signkey_names[type]); |
51 #endif | 73 } |
52 #ifdef DROPBEAR_DSS | 74 return signkey_names[type]; |
53 if (type == DROPBEAR_SIGNKEY_DSS) { | 75 } |
54 *namelen = SSH_SIGNKEY_DSS_LEN; | 76 |
55 return SSH_SIGNKEY_DSS; | 77 /* Returns DROPBEAR_SIGNKEY_NONE if none match */ |
56 } | 78 enum signkey_type signkey_type_from_name(const char* name, unsigned int namelen) { |
57 #endif | 79 int i; |
58 dropbear_exit("Bad key type %d", type); | 80 for (i = 0; i < DROPBEAR_SIGNKEY_NUM_NAMED; i++) { |
59 return NULL; /* notreached */ | 81 const char *fixed_name = signkey_names[i]; |
60 } | 82 if (namelen == strlen(fixed_name) |
61 | 83 && memcmp(fixed_name, name, namelen) == 0) { |
62 /* Returns DROPBEAR_SIGNKEY_RSA, DROPBEAR_SIGNKEY_DSS, | 84 return i; |
63 * or DROPBEAR_SIGNKEY_NONE */ | 85 } |
64 int signkey_type_from_name(const char* name, int namelen) { | 86 } |
65 | |
66 #ifdef DROPBEAR_RSA | |
67 if (namelen == SSH_SIGNKEY_RSA_LEN | |
68 && memcmp(name, SSH_SIGNKEY_RSA, SSH_SIGNKEY_RSA_LEN) == 0) { | |
69 return DROPBEAR_SIGNKEY_RSA; | |
70 } | |
71 #endif | |
72 #ifdef DROPBEAR_DSS | |
73 if (namelen == SSH_SIGNKEY_DSS_LEN | |
74 && memcmp(name, SSH_SIGNKEY_DSS, SSH_SIGNKEY_DSS_LEN) == 0) { | |
75 return DROPBEAR_SIGNKEY_DSS; | |
76 } | |
77 #endif | |
78 | 87 |
79 TRACE(("signkey_type_from_name unexpected key type.")) | 88 TRACE(("signkey_type_from_name unexpected key type.")) |
80 | 89 |
81 return DROPBEAR_SIGNKEY_NONE; | 90 return DROPBEAR_SIGNKEY_NONE; |
82 } | 91 } |
127 if (ret == DROPBEAR_FAILURE) { | 136 if (ret == DROPBEAR_FAILURE) { |
128 m_free(key->rsakey); | 137 m_free(key->rsakey); |
129 } | 138 } |
130 } | 139 } |
131 #endif | 140 #endif |
141 #ifdef DROPBEAR_ECDSA | |
142 if (keytype == DROPBEAR_SIGNKEY_ECDSA_NISTP256 | |
143 || keytype == DROPBEAR_SIGNKEY_ECDSA_NISTP384 | |
144 || keytype == DROPBEAR_SIGNKEY_ECDSA_NISTP521) { | |
145 if (key->ecckey) { | |
146 ecc_free(key->ecckey); | |
147 } | |
148 key->ecckey = buf_get_ecdsa_pub_key(buf); | |
149 if (key->ecckey) { | |
150 ret = DROPBEAR_SUCCESS; | |
151 } | |
152 } | |
153 #endif | |
132 | 154 |
133 TRACE(("leave buf_get_pub_key")) | 155 TRACE(("leave buf_get_pub_key")) |
134 | 156 |
135 return ret; | 157 return ret; |
136 | 158 |
180 if (ret == DROPBEAR_FAILURE) { | 202 if (ret == DROPBEAR_FAILURE) { |
181 m_free(key->rsakey); | 203 m_free(key->rsakey); |
182 } | 204 } |
183 } | 205 } |
184 #endif | 206 #endif |
207 #ifdef DROPBEAR_ECDSA | |
208 if (keytype == DROPBEAR_SIGNKEY_ECDSA_NISTP256 | |
209 || keytype == DROPBEAR_SIGNKEY_ECDSA_NISTP384 | |
210 || keytype == DROPBEAR_SIGNKEY_ECDSA_NISTP521) { | |
211 if (key->ecckey) { | |
212 ecc_free(key->ecckey); | |
213 } | |
214 key->ecckey = buf_get_ecdsa_priv_key(buf); | |
215 if (key->ecckey) { | |
216 ret = DROPBEAR_SUCCESS; | |
217 } | |
218 } | |
219 #endif | |
185 | 220 |
186 TRACE(("leave buf_get_priv_key")) | 221 TRACE(("leave buf_get_priv_key")) |
187 | 222 |
188 return ret; | 223 return ret; |
189 | 224 |
203 } | 238 } |
204 #endif | 239 #endif |
205 #ifdef DROPBEAR_RSA | 240 #ifdef DROPBEAR_RSA |
206 if (type == DROPBEAR_SIGNKEY_RSA) { | 241 if (type == DROPBEAR_SIGNKEY_RSA) { |
207 buf_put_rsa_pub_key(pubkeys, key->rsakey); | 242 buf_put_rsa_pub_key(pubkeys, key->rsakey); |
243 } | |
244 #endif | |
245 #ifdef DROPBEAR_ECDSA | |
246 if (type == DROPBEAR_SIGNKEY_ECDSA_NISTP256 | |
247 || type == DROPBEAR_SIGNKEY_ECDSA_NISTP384 | |
248 || type == DROPBEAR_SIGNKEY_ECDSA_NISTP521) { | |
249 buf_put_ecdsa_pub_key(pubkeys, key->ecckey); | |
208 } | 250 } |
209 #endif | 251 #endif |
210 if (pubkeys->len == 0) { | 252 if (pubkeys->len == 0) { |
211 dropbear_exit("Bad key types in buf_put_pub_key"); | 253 dropbear_exit("Bad key types in buf_put_pub_key"); |
212 } | 254 } |
234 buf_put_rsa_priv_key(buf, key->rsakey); | 276 buf_put_rsa_priv_key(buf, key->rsakey); |
235 TRACE(("leave buf_put_priv_key: rsa done")) | 277 TRACE(("leave buf_put_priv_key: rsa done")) |
236 return; | 278 return; |
237 } | 279 } |
238 #endif | 280 #endif |
281 #ifdef DROPBEAR_ECDSA | |
282 if (type == DROPBEAR_SIGNKEY_ECDSA_NISTP256 | |
283 || type == DROPBEAR_SIGNKEY_ECDSA_NISTP384 | |
284 || type == DROPBEAR_SIGNKEY_ECDSA_NISTP521) { | |
285 buf_put_ecdsa_pub_key(buf, key->ecckey); | |
286 return; | |
287 } | |
288 #endif | |
239 dropbear_exit("Bad key types in put pub key"); | 289 dropbear_exit("Bad key types in put pub key"); |
240 } | 290 } |
241 | 291 |
242 void sign_key_free(sign_key *key) { | 292 void sign_key_free(sign_key *key) { |
243 | 293 |
249 #endif | 299 #endif |
250 #ifdef DROPBEAR_RSA | 300 #ifdef DROPBEAR_RSA |
251 rsa_key_free(key->rsakey); | 301 rsa_key_free(key->rsakey); |
252 key->rsakey = NULL; | 302 key->rsakey = NULL; |
253 #endif | 303 #endif |
304 #ifdef DROPBEAR_ECDSA | |
305 if (key->ecckey) { | |
306 ecc_free(key->ecckey); | |
307 key->ecckey = NULL; | |
308 } | |
309 #endif | |
254 | 310 |
255 m_free(key->filename); | 311 m_free(key->filename); |
256 | 312 |
257 m_free(key); | 313 m_free(key); |
258 TRACE(("leave sign_key_free")) | 314 TRACE(("leave sign_key_free")) |
259 } | 315 } |
260 | 316 |
261 static char hexdig(unsigned char x) { | 317 static char hexdig(unsigned char x) { |
262 | |
263 if (x > 0xf) | 318 if (x > 0xf) |
264 return 'X'; | 319 return 'X'; |
265 | 320 |
266 if (x < 10) | 321 if (x < 10) |
267 return '0' + x; | 322 return '0' + x; |
321 /* skip the size int of the string - this is a bit messy */ | 376 /* skip the size int of the string - this is a bit messy */ |
322 sha1_process(&hs, keyblob, keybloblen); | 377 sha1_process(&hs, keyblob, keybloblen); |
323 | 378 |
324 sha1_done(&hs, hash); | 379 sha1_done(&hs, hash); |
325 | 380 |
326 /* "sha1 hexfingerprinthere\0", each hex digit is "AB:" etc */ | 381 /* "sha1!! hexfingerprinthere\0", each hex digit is "AB:" etc */ |
327 buflen = 5 + 3*SHA1_HASH_SIZE; | 382 buflen = 7 + 3*SHA1_HASH_SIZE; |
328 ret = (char*)m_malloc(buflen); | 383 ret = (char*)m_malloc(buflen); |
329 | 384 |
330 strcpy(ret, "sha1 "); | 385 strcpy(ret, "sha1!! "); |
331 | 386 |
332 for (i = 0; i < SHA1_HASH_SIZE; i++) { | 387 for (i = 0; i < SHA1_HASH_SIZE; i++) { |
333 unsigned int pos = 5 + 3*i; | 388 unsigned int pos = 7 + 3*i; |
334 ret[pos] = hexdig(hash[i] >> 4); | 389 ret[pos] = hexdig(hash[i] >> 4); |
335 ret[pos+1] = hexdig(hash[i] & 0x0f); | 390 ret[pos+1] = hexdig(hash[i] & 0x0f); |
336 ret[pos+2] = ':'; | 391 ret[pos+2] = ':'; |
337 } | 392 } |
338 ret[buflen-1] = 0x0; | 393 ret[buflen-1] = 0x0; |
364 } | 419 } |
365 #endif | 420 #endif |
366 #ifdef DROPBEAR_RSA | 421 #ifdef DROPBEAR_RSA |
367 if (type == DROPBEAR_SIGNKEY_RSA) { | 422 if (type == DROPBEAR_SIGNKEY_RSA) { |
368 buf_put_rsa_sign(sigblob, key->rsakey, data_buf); | 423 buf_put_rsa_sign(sigblob, key->rsakey, data_buf); |
424 } | |
425 #endif | |
426 #ifdef DROPBEAR_ECDSA | |
427 if (type == DROPBEAR_SIGNKEY_ECDSA_NISTP256 | |
428 || type == DROPBEAR_SIGNKEY_ECDSA_NISTP384 | |
429 || type == DROPBEAR_SIGNKEY_ECDSA_NISTP521) { | |
430 buf_put_ecdsa_sign(sigblob, key->ecckey, data_buf); | |
369 } | 431 } |
370 #endif | 432 #endif |
371 if (sigblob->len == 0) { | 433 if (sigblob->len == 0) { |
372 dropbear_exit("Non-matching signing type"); | 434 dropbear_exit("Non-matching signing type"); |
373 } | 435 } |
382 * buf is undefined. If SUCCESS is returned, buf will be positioned after the | 444 * buf is undefined. If SUCCESS is returned, buf will be positioned after the |
383 * signature blob */ | 445 * signature blob */ |
384 int buf_verify(buffer * buf, sign_key *key, buffer *data_buf) { | 446 int buf_verify(buffer * buf, sign_key *key, buffer *data_buf) { |
385 | 447 |
386 unsigned int bloblen; | 448 unsigned int bloblen; |
387 unsigned char * ident = NULL; | 449 unsigned char * type_name = NULL; |
388 unsigned int identlen = 0; | 450 unsigned int type_name_len = 0; |
389 | 451 |
390 TRACE(("enter buf_verify")) | 452 TRACE(("enter buf_verify")) |
391 | 453 |
392 bloblen = buf_getint(buf); | 454 bloblen = buf_getint(buf); |
393 ident = buf_getstring(buf, &identlen); | 455 type_name = buf_getstring(buf, &type_name_len); |
394 | 456 enum signkey_type type = signkey_type_from_name(type_name, type_name_len); |
395 #ifdef DROPBEAR_DSS | 457 m_free(type_name); |
396 if (bloblen == DSS_SIGNATURE_SIZE && | 458 |
397 memcmp(ident, SSH_SIGNKEY_DSS, identlen) == 0) { | 459 #ifdef DROPBEAR_DSS |
398 m_free(ident); | 460 if (type == DROPBEAR_SIGNKEY_DSS) { |
399 if (key->dsskey == NULL) { | 461 if (key->dsskey == NULL) { |
400 dropbear_exit("No DSS key to verify signature"); | 462 dropbear_exit("No DSS key to verify signature"); |
401 } | 463 } |
402 return buf_dss_verify(buf, key->dsskey, data_buf); | 464 return buf_dss_verify(buf, key->dsskey, data_buf); |
403 } | 465 } |
404 #endif | 466 #endif |
405 | 467 |
406 #ifdef DROPBEAR_RSA | 468 #ifdef DROPBEAR_RSA |
407 if (memcmp(ident, SSH_SIGNKEY_RSA, identlen) == 0) { | 469 if (type == DROPBEAR_SIGNKEY_RSA) { |
408 m_free(ident); | |
409 if (key->rsakey == NULL) { | 470 if (key->rsakey == NULL) { |
410 dropbear_exit("No RSA key to verify signature"); | 471 dropbear_exit("No RSA key to verify signature"); |
411 } | 472 } |
412 return buf_rsa_verify(buf, key->rsakey, data_buf); | 473 return buf_rsa_verify(buf, key->rsakey, data_buf); |
413 } | 474 } |
414 #endif | 475 #endif |
415 | 476 #ifdef DROPBEAR_ECDSA |
416 m_free(ident); | 477 if (type == DROPBEAR_SIGNKEY_ECDSA_NISTP256 |
478 || type == DROPBEAR_SIGNKEY_ECDSA_NISTP384 | |
479 || type == DROPBEAR_SIGNKEY_ECDSA_NISTP521) { | |
480 return buf_ecdsa_verify(buf, key->ecckey, data_buf); | |
481 } | |
482 #endif | |
483 | |
417 dropbear_exit("Non-matching signing type"); | 484 dropbear_exit("Non-matching signing type"); |
418 return DROPBEAR_FAILURE; | 485 return DROPBEAR_FAILURE; |
419 } | 486 } |
420 #endif /* DROPBEAR_SIGNKEY_VERIFY */ | 487 #endif /* DROPBEAR_SIGNKEY_VERIFY */ |
421 | 488 |