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