comparison signkey.c @ 839:33207ed1174b

Merge in ECC
author Matt Johnston <matt@ucc.asn.au>
date Mon, 21 Oct 2013 22:57:21 +0800
parents 75509065db53
children d4ce5269a439
comparison
equal deleted inserted replaced
834:e378da7eae5d 839:33207ed1174b
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 "ecdsa" // for keygen
44 #endif // DROPBEAR_ECDSA
45 };
30 46
31 /* malloc a new sign_key and set the dss and rsa keys to NULL */ 47 /* malloc a new sign_key and set the dss and rsa keys to NULL */
32 sign_key * new_sign_key() { 48 sign_key * new_sign_key() {
33 49
34 sign_key * ret; 50 sign_key * ret;
35 51
36 ret = (sign_key*)m_malloc(sizeof(sign_key)); 52 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; 53 ret->type = DROPBEAR_SIGNKEY_NONE;
45 ret->source = SIGNKEY_SOURCE_INVALID; 54 ret->source = SIGNKEY_SOURCE_INVALID;
46 return ret; 55 return ret;
47 } 56 }
48 57
49 /* Returns "ssh-dss" or "ssh-rsa" corresponding to the type. Exits fatally 58 /* Returns key name corresponding to the type. Exits fatally
50 * if the type is invalid */ 59 * if the type is invalid */
51 const char* signkey_name_from_type(int type, int *namelen) { 60 const char* signkey_name_from_type(enum signkey_type type, unsigned int *namelen) {
52 61 if (type >= DROPBEAR_SIGNKEY_NUM_NAMED) {
53 #ifdef DROPBEAR_RSA 62 dropbear_exit("Bad key type %d", type);
54 if (type == DROPBEAR_SIGNKEY_RSA) { 63 }
55 *namelen = SSH_SIGNKEY_RSA_LEN; 64
56 return SSH_SIGNKEY_RSA; 65 if (namelen) {
57 } 66 *namelen = strlen(signkey_names[type]);
58 #endif 67 }
59 #ifdef DROPBEAR_DSS 68 return signkey_names[type];
60 if (type == DROPBEAR_SIGNKEY_DSS) { 69 }
61 *namelen = SSH_SIGNKEY_DSS_LEN; 70
62 return SSH_SIGNKEY_DSS; 71 /* Returns DROPBEAR_SIGNKEY_NONE if none match */
63 } 72 enum signkey_type signkey_type_from_name(const char* name, unsigned int namelen) {
64 #endif 73 int i;
65 dropbear_exit("Bad key type %d", type); 74 for (i = 0; i < DROPBEAR_SIGNKEY_NUM_NAMED; i++) {
66 return NULL; /* notreached */ 75 const char *fixed_name = signkey_names[i];
67 } 76 if (namelen == strlen(fixed_name)
68 77 && memcmp(fixed_name, name, namelen) == 0) {
69 /* Returns DROPBEAR_SIGNKEY_RSA, DROPBEAR_SIGNKEY_DSS, 78
70 * or DROPBEAR_SIGNKEY_NONE */ 79 #ifdef DROPBEAR_ECDSA
71 int signkey_type_from_name(const char* name, int namelen) { 80 /* Some of the ECDSA key sizes are defined even if they're not compiled in */
72 81 if (0
73 #ifdef DROPBEAR_RSA 82 #ifndef DROPBEAR_ECC_256
74 if (namelen == SSH_SIGNKEY_RSA_LEN 83 || i == DROPBEAR_SIGNKEY_ECDSA_NISTP256
75 && memcmp(name, SSH_SIGNKEY_RSA, SSH_SIGNKEY_RSA_LEN) == 0) { 84 #endif
76 return DROPBEAR_SIGNKEY_RSA; 85 #ifndef DROPBEAR_ECC_384
77 } 86 || i == DROPBEAR_SIGNKEY_ECDSA_NISTP384
78 #endif 87 #endif
79 #ifdef DROPBEAR_DSS 88 #ifndef DROPBEAR_ECC_521
80 if (namelen == SSH_SIGNKEY_DSS_LEN 89 || i == DROPBEAR_SIGNKEY_ECDSA_NISTP521
81 && memcmp(name, SSH_SIGNKEY_DSS, SSH_SIGNKEY_DSS_LEN) == 0) { 90 #endif
82 return DROPBEAR_SIGNKEY_DSS; 91 ) {
83 } 92 TRACE(("attempt to use ecdsa type %d not compiled in", i))
84 #endif 93 return DROPBEAR_SIGNKEY_NONE;
94 }
95 #endif
96
97 return i;
98 }
99 }
85 100
86 TRACE(("signkey_type_from_name unexpected key type.")) 101 TRACE(("signkey_type_from_name unexpected key type."))
87 102
88 return DROPBEAR_SIGNKEY_NONE; 103 return DROPBEAR_SIGNKEY_NONE;
89 } 104 }
105
106 #ifdef DROPBEAR_ECDSA
107 ecc_key **
108 signkey_ecc_key_ptr(sign_key *key, enum signkey_type ecc_type) {
109 switch (ecc_type) {
110 case DROPBEAR_SIGNKEY_ECDSA_NISTP256:
111 return &key->ecckey256;
112 case DROPBEAR_SIGNKEY_ECDSA_NISTP384:
113 return &key->ecckey384;
114 case DROPBEAR_SIGNKEY_ECDSA_NISTP521:
115 return &key->ecckey521;
116 default:
117 return NULL;
118 }
119 }
120 #endif
90 121
91 /* returns DROPBEAR_SUCCESS on success, DROPBEAR_FAILURE on fail. 122 /* returns DROPBEAR_SUCCESS on success, DROPBEAR_FAILURE on fail.
92 * type should be set by the caller to specify the type to read, and 123 * 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) */ 124 * 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) { 125 int buf_get_pub_key(buffer *buf, sign_key *key, int *type) {
134 if (ret == DROPBEAR_FAILURE) { 165 if (ret == DROPBEAR_FAILURE) {
135 m_free(key->rsakey); 166 m_free(key->rsakey);
136 } 167 }
137 } 168 }
138 #endif 169 #endif
170 #ifdef DROPBEAR_ECDSA
171 {
172 ecc_key **eck = signkey_ecc_key_ptr(key, keytype);
173 if (eck) {
174 if (*eck) {
175 ecc_free(*eck);
176 *eck = NULL;
177 }
178 *eck = buf_get_ecdsa_pub_key(buf);
179 if (*eck) {
180 ret = DROPBEAR_SUCCESS;
181 }
182 }
183 }
184 #endif
139 185
140 TRACE2(("leave buf_get_pub_key")) 186 TRACE2(("leave buf_get_pub_key"))
141 187
142 return ret; 188 return ret;
143 189
187 if (ret == DROPBEAR_FAILURE) { 233 if (ret == DROPBEAR_FAILURE) {
188 m_free(key->rsakey); 234 m_free(key->rsakey);
189 } 235 }
190 } 236 }
191 #endif 237 #endif
238 #ifdef DROPBEAR_ECDSA
239 {
240 ecc_key **eck = signkey_ecc_key_ptr(key, keytype);
241 if (eck) {
242 if (*eck) {
243 ecc_free(*eck);
244 *eck = NULL;
245 }
246 *eck = buf_get_ecdsa_priv_key(buf);
247 if (*eck) {
248 ret = DROPBEAR_SUCCESS;
249 }
250 }
251 }
252 #endif
192 253
193 TRACE2(("leave buf_get_priv_key")) 254 TRACE2(("leave buf_get_priv_key"))
194 255
195 return ret; 256 return ret;
196 257
212 #ifdef DROPBEAR_RSA 273 #ifdef DROPBEAR_RSA
213 if (type == DROPBEAR_SIGNKEY_RSA) { 274 if (type == DROPBEAR_SIGNKEY_RSA) {
214 buf_put_rsa_pub_key(pubkeys, key->rsakey); 275 buf_put_rsa_pub_key(pubkeys, key->rsakey);
215 } 276 }
216 #endif 277 #endif
278 #ifdef DROPBEAR_ECDSA
279 {
280 ecc_key **eck = signkey_ecc_key_ptr(key, type);
281 if (eck) {
282 buf_put_ecdsa_pub_key(pubkeys, *eck);
283 }
284 }
285 #endif
217 if (pubkeys->len == 0) { 286 if (pubkeys->len == 0) {
218 dropbear_exit("Bad key types in buf_put_pub_key"); 287 dropbear_exit("Bad key types in buf_put_pub_key");
219 } 288 }
220 289
221 buf_setpos(pubkeys, 0); 290 buf_putbufstring(buf, pubkeys);
222 buf_putstring(buf, buf_getptr(pubkeys, pubkeys->len),
223 pubkeys->len);
224
225 buf_free(pubkeys); 291 buf_free(pubkeys);
226 TRACE2(("leave buf_put_pub_key")) 292 TRACE2(("leave buf_put_pub_key"))
227 } 293 }
228 294
229 /* type is either DROPBEAR_SIGNKEY_DSS or DROPBEAR_SIGNKEY_RSA */ 295 /* type is either DROPBEAR_SIGNKEY_DSS or DROPBEAR_SIGNKEY_RSA */
244 buf_put_rsa_priv_key(buf, key->rsakey); 310 buf_put_rsa_priv_key(buf, key->rsakey);
245 TRACE(("leave buf_put_priv_key: rsa done")) 311 TRACE(("leave buf_put_priv_key: rsa done"))
246 return; 312 return;
247 } 313 }
248 #endif 314 #endif
315 #ifdef DROPBEAR_ECDSA
316 {
317 ecc_key **eck = signkey_ecc_key_ptr(key, type);
318 if (eck) {
319 buf_put_ecdsa_priv_key(buf, *eck);
320 TRACE(("leave buf_put_priv_key: ecdsa done"))
321 return;
322 }
323 }
324 #endif
249 dropbear_exit("Bad key types in put pub key"); 325 dropbear_exit("Bad key types in put pub key");
250 } 326 }
251 327
252 void sign_key_free(sign_key *key) { 328 void sign_key_free(sign_key *key) {
253 329
259 #endif 335 #endif
260 #ifdef DROPBEAR_RSA 336 #ifdef DROPBEAR_RSA
261 rsa_key_free(key->rsakey); 337 rsa_key_free(key->rsakey);
262 key->rsakey = NULL; 338 key->rsakey = NULL;
263 #endif 339 #endif
340 #ifdef DROPBEAR_ECDSA
341 if (key->ecckey256) {
342 ecc_free(key->ecckey256);
343 key->ecckey256 = NULL;
344 }
345 if (key->ecckey384) {
346 ecc_free(key->ecckey384);
347 key->ecckey384 = NULL;
348 }
349 if (key->ecckey521) {
350 ecc_free(key->ecckey521);
351 key->ecckey521 = NULL;
352 }
353 #endif
264 354
265 m_free(key->filename); 355 m_free(key->filename);
266 356
267 m_free(key); 357 m_free(key);
268 TRACE2(("leave sign_key_free")) 358 TRACE2(("leave sign_key_free"))
269 } 359 }
270 360
271 static char hexdig(unsigned char x) { 361 static char hexdig(unsigned char x) {
272
273 if (x > 0xf) 362 if (x > 0xf)
274 return 'X'; 363 return 'X';
275 364
276 if (x < 10) 365 if (x < 10)
277 return '0' + x; 366 return '0' + x;
331 /* skip the size int of the string - this is a bit messy */ 420 /* skip the size int of the string - this is a bit messy */
332 sha1_process(&hs, keyblob, keybloblen); 421 sha1_process(&hs, keyblob, keybloblen);
333 422
334 sha1_done(&hs, hash); 423 sha1_done(&hs, hash);
335 424
336 /* "sha1 hexfingerprinthere\0", each hex digit is "AB:" etc */ 425 /* "sha1!! hexfingerprinthere\0", each hex digit is "AB:" etc */
337 buflen = 5 + 3*SHA1_HASH_SIZE; 426 buflen = 7 + 3*SHA1_HASH_SIZE;
338 ret = (char*)m_malloc(buflen); 427 ret = (char*)m_malloc(buflen);
339 428
340 strcpy(ret, "sha1 "); 429 strcpy(ret, "sha1!! ");
341 430
342 for (i = 0; i < SHA1_HASH_SIZE; i++) { 431 for (i = 0; i < SHA1_HASH_SIZE; i++) {
343 unsigned int pos = 5 + 3*i; 432 unsigned int pos = 7 + 3*i;
344 ret[pos] = hexdig(hash[i] >> 4); 433 ret[pos] = hexdig(hash[i] >> 4);
345 ret[pos+1] = hexdig(hash[i] & 0x0f); 434 ret[pos+1] = hexdig(hash[i] & 0x0f);
346 ret[pos+2] = ':'; 435 ret[pos+2] = ':';
347 } 436 }
348 ret[buflen-1] = 0x0; 437 ret[buflen-1] = 0x0;
362 return sign_key_sha1_fingerprint(keyblob, keybloblen); 451 return sign_key_sha1_fingerprint(keyblob, keybloblen);
363 #endif 452 #endif
364 } 453 }
365 454
366 void buf_put_sign(buffer* buf, sign_key *key, int type, 455 void buf_put_sign(buffer* buf, sign_key *key, int type,
367 const unsigned char *data, unsigned int len) { 456 buffer *data_buf) {
368
369 buffer *sigblob; 457 buffer *sigblob;
370 sigblob = buf_new(MAX_PUBKEY_SIZE); 458 sigblob = buf_new(MAX_PUBKEY_SIZE);
371 459
372 #ifdef DROPBEAR_DSS 460 #ifdef DROPBEAR_DSS
373 if (type == DROPBEAR_SIGNKEY_DSS) { 461 if (type == DROPBEAR_SIGNKEY_DSS) {
374 buf_put_dss_sign(sigblob, key->dsskey, data, len); 462 buf_put_dss_sign(sigblob, key->dsskey, data_buf);
375 } 463 }
376 #endif 464 #endif
377 #ifdef DROPBEAR_RSA 465 #ifdef DROPBEAR_RSA
378 if (type == DROPBEAR_SIGNKEY_RSA) { 466 if (type == DROPBEAR_SIGNKEY_RSA) {
379 buf_put_rsa_sign(sigblob, key->rsakey, data, len); 467 buf_put_rsa_sign(sigblob, key->rsakey, data_buf);
468 }
469 #endif
470 #ifdef DROPBEAR_ECDSA
471 {
472 ecc_key **eck = signkey_ecc_key_ptr(key, type);
473 if (eck) {
474 buf_put_ecdsa_sign(sigblob, *eck, data_buf);
475 }
380 } 476 }
381 #endif 477 #endif
382 if (sigblob->len == 0) { 478 if (sigblob->len == 0) {
383 dropbear_exit("Non-matching signing type"); 479 dropbear_exit("Non-matching signing type");
384 } 480 }
385 buf_setpos(sigblob, 0); 481 buf_putbufstring(buf, sigblob);
386 buf_putstring(buf, buf_getptr(sigblob, sigblob->len),
387 sigblob->len);
388
389 buf_free(sigblob); 482 buf_free(sigblob);
390 483
391 } 484 }
392 485
393 #ifdef DROPBEAR_SIGNKEY_VERIFY 486 #ifdef DROPBEAR_SIGNKEY_VERIFY
394 /* Return DROPBEAR_SUCCESS or DROPBEAR_FAILURE. 487 /* Return DROPBEAR_SUCCESS or DROPBEAR_FAILURE.
395 * If FAILURE is returned, the position of 488 * If FAILURE is returned, the position of
396 * buf is undefined. If SUCCESS is returned, buf will be positioned after the 489 * buf is undefined. If SUCCESS is returned, buf will be positioned after the
397 * signature blob */ 490 * signature blob */
398 int buf_verify(buffer * buf, sign_key *key, const unsigned char *data, 491 int buf_verify(buffer * buf, sign_key *key, buffer *data_buf) {
399 unsigned int len) {
400 492
401 unsigned int bloblen; 493 unsigned int bloblen;
402 unsigned char * ident = NULL; 494 unsigned char * type_name = NULL;
403 unsigned int identlen = 0; 495 unsigned int type_name_len = 0;
404 496
405 TRACE(("enter buf_verify")) 497 TRACE(("enter buf_verify"))
406 498
407 bloblen = buf_getint(buf); 499 bloblen = buf_getint(buf);
408 ident = buf_getstring(buf, &identlen); 500 type_name = buf_getstring(buf, &type_name_len);
409 501 enum signkey_type type = signkey_type_from_name(type_name, type_name_len);
410 #ifdef DROPBEAR_DSS 502 m_free(type_name);
411 if (bloblen == DSS_SIGNATURE_SIZE && 503
412 memcmp(ident, SSH_SIGNKEY_DSS, identlen) == 0) { 504 #ifdef DROPBEAR_DSS
413 m_free(ident); 505 if (type == DROPBEAR_SIGNKEY_DSS) {
414 if (key->dsskey == NULL) { 506 if (key->dsskey == NULL) {
415 dropbear_exit("No DSS key to verify signature"); 507 dropbear_exit("No DSS key to verify signature");
416 } 508 }
417 return buf_dss_verify(buf, key->dsskey, data, len); 509 return buf_dss_verify(buf, key->dsskey, data_buf);
418 } 510 }
419 #endif 511 #endif
420 512
421 #ifdef DROPBEAR_RSA 513 #ifdef DROPBEAR_RSA
422 if (memcmp(ident, SSH_SIGNKEY_RSA, identlen) == 0) { 514 if (type == DROPBEAR_SIGNKEY_RSA) {
423 m_free(ident);
424 if (key->rsakey == NULL) { 515 if (key->rsakey == NULL) {
425 dropbear_exit("No RSA key to verify signature"); 516 dropbear_exit("No RSA key to verify signature");
426 } 517 }
427 return buf_rsa_verify(buf, key->rsakey, data, len); 518 return buf_rsa_verify(buf, key->rsakey, data_buf);
428 } 519 }
429 #endif 520 #endif
430 521 #ifdef DROPBEAR_ECDSA
431 m_free(ident); 522 {
523 ecc_key **eck = signkey_ecc_key_ptr(key, type);
524 if (eck) {
525 return buf_ecdsa_verify(buf, *eck, data_buf);
526 }
527 }
528 #endif
529
432 dropbear_exit("Non-matching signing type"); 530 dropbear_exit("Non-matching signing type");
433 return DROPBEAR_FAILURE; 531 return DROPBEAR_FAILURE;
434 } 532 }
435 #endif /* DROPBEAR_SIGNKEY_VERIFY */ 533 #endif /* DROPBEAR_SIGNKEY_VERIFY */
436 534