Mercurial > dropbear
comparison signkey.c @ 1733:d529a52b2f7c coverity coverity
merge coverity from main
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Fri, 26 Jun 2020 21:07:34 +0800 |
parents | d5d25ce2a2ed |
children | 064f5be2fc45 |
comparison
equal
deleted
inserted
replaced
1643:b59623a64678 | 1733:d529a52b2f7c |
---|---|
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" | 30 #include "ecdsa.h" |
31 #include "rsa.h" | |
32 #include "dss.h" | |
33 #include "ed25519.h" | |
31 | 34 |
32 static const char * const signkey_names[DROPBEAR_SIGNKEY_NUM_NAMED] = { | 35 static const char * const signkey_names[DROPBEAR_SIGNKEY_NUM_NAMED] = { |
33 #if DROPBEAR_RSA | 36 #if DROPBEAR_RSA |
34 "ssh-rsa", | 37 "ssh-rsa", |
35 #endif | 38 #endif |
37 "ssh-dss", | 40 "ssh-dss", |
38 #endif | 41 #endif |
39 #if DROPBEAR_ECDSA | 42 #if DROPBEAR_ECDSA |
40 "ecdsa-sha2-nistp256", | 43 "ecdsa-sha2-nistp256", |
41 "ecdsa-sha2-nistp384", | 44 "ecdsa-sha2-nistp384", |
42 "ecdsa-sha2-nistp521" | 45 "ecdsa-sha2-nistp521", |
43 #endif /* DROPBEAR_ECDSA */ | 46 #endif /* DROPBEAR_ECDSA */ |
47 #if DROPBEAR_ED25519 | |
48 "ssh-ed25519", | |
49 #endif /* DROPBEAR_ED25519 */ | |
50 /* "rsa-sha2-256" is special-cased below since it is only a signature name, not key type */ | |
44 }; | 51 }; |
45 | 52 |
46 /* 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 */ |
47 sign_key * new_sign_key() { | 54 sign_key * new_sign_key() { |
48 | 55 |
100 TRACE(("signkey_type_from_name unexpected key type.")) | 107 TRACE(("signkey_type_from_name unexpected key type.")) |
101 | 108 |
102 return DROPBEAR_SIGNKEY_NONE; | 109 return DROPBEAR_SIGNKEY_NONE; |
103 } | 110 } |
104 | 111 |
112 /* Special case for rsa-sha2-256. This could be generalised if more | |
113 signature names are added that aren't 1-1 with public key names */ | |
114 const char* signature_name_from_type(enum signature_type type, unsigned int *namelen) { | |
115 #if DROPBEAR_RSA_SHA256 | |
116 if (type == DROPBEAR_SIGNATURE_RSA_SHA256) { | |
117 if (namelen) { | |
118 *namelen = strlen(SSH_SIGNATURE_RSA_SHA256); | |
119 } | |
120 return SSH_SIGNATURE_RSA_SHA256; | |
121 } | |
122 #endif | |
123 #if DROPBEAR_RSA_SHA1 | |
124 if (type == DROPBEAR_SIGNATURE_RSA_SHA1) { | |
125 if (namelen) { | |
126 *namelen = strlen(SSH_SIGNKEY_RSA); | |
127 } | |
128 return SSH_SIGNKEY_RSA; | |
129 } | |
130 #endif | |
131 return signkey_name_from_type((enum signkey_type)type, namelen); | |
132 } | |
133 | |
134 /* Returns DROPBEAR_SIGNATURE_NONE if none match */ | |
135 enum signature_type signature_type_from_name(const char* name, unsigned int namelen) { | |
136 #if DROPBEAR_RSA_SHA256 | |
137 if (namelen == strlen(SSH_SIGNATURE_RSA_SHA256) | |
138 && memcmp(name, SSH_SIGNATURE_RSA_SHA256, namelen) == 0) { | |
139 return DROPBEAR_SIGNATURE_RSA_SHA256; | |
140 } | |
141 #endif | |
142 #if DROPBEAR_RSA_SHA1 | |
143 if (namelen == strlen(SSH_SIGNKEY_RSA) | |
144 && memcmp(name, SSH_SIGNKEY_RSA, namelen) == 0) { | |
145 return DROPBEAR_SIGNATURE_RSA_SHA1; | |
146 } | |
147 #endif | |
148 return (enum signature_type)signkey_type_from_name(name, namelen); | |
149 } | |
150 | |
151 /* Returns the signature type from a key type. Must not be called | |
152 with RSA keytype */ | |
153 enum signature_type signature_type_from_signkey(enum signkey_type keytype) { | |
154 #if DROPBEAR_RSA | |
155 assert(keytype != DROPBEAR_SIGNKEY_RSA); | |
156 #endif | |
157 assert(keytype < DROPBEAR_SIGNKEY_NUM_NAMED); | |
158 return (enum signature_type)keytype; | |
159 } | |
160 | |
161 enum signkey_type signkey_type_from_signature(enum signature_type sigtype) { | |
162 #if DROPBEAR_RSA_SHA256 | |
163 if (sigtype == DROPBEAR_SIGNATURE_RSA_SHA256) { | |
164 return DROPBEAR_SIGNKEY_RSA; | |
165 } | |
166 #endif | |
167 #if DROPBEAR_RSA_SHA1 | |
168 if (sigtype == DROPBEAR_SIGNATURE_RSA_SHA1) { | |
169 return DROPBEAR_SIGNKEY_RSA; | |
170 } | |
171 #endif | |
172 assert((int)sigtype < (int)DROPBEAR_SIGNKEY_NUM_NAMED); | |
173 return (enum signkey_type)sigtype; | |
174 } | |
175 | |
105 /* Returns a pointer to the key part specific to "type". | 176 /* Returns a pointer to the key part specific to "type". |
106 Be sure to check both (ret != NULL) and (*ret != NULL) */ | 177 Be sure to check both (ret != NULL) and (*ret != NULL) */ |
107 void ** | 178 void ** |
108 signkey_key_ptr(sign_key *key, enum signkey_type type) { | 179 signkey_key_ptr(sign_key *key, enum signkey_type type) { |
109 switch (type) { | 180 switch (type) { |
181 #if DROPBEAR_ED25519 | |
182 case DROPBEAR_SIGNKEY_ED25519: | |
183 return (void**)&key->ed25519key; | |
184 #endif | |
110 #if DROPBEAR_ECDSA | 185 #if DROPBEAR_ECDSA |
111 #if DROPBEAR_ECC_256 | 186 #if DROPBEAR_ECC_256 |
112 case DROPBEAR_SIGNKEY_ECDSA_NISTP256: | 187 case DROPBEAR_SIGNKEY_ECDSA_NISTP256: |
113 return (void**)&key->ecckey256; | 188 return (void**)&key->ecckey256; |
114 #endif | 189 #endif |
198 ret = DROPBEAR_SUCCESS; | 273 ret = DROPBEAR_SUCCESS; |
199 } | 274 } |
200 } | 275 } |
201 } | 276 } |
202 #endif | 277 #endif |
278 #if DROPBEAR_ED25519 | |
279 if (keytype == DROPBEAR_SIGNKEY_ED25519) { | |
280 ed25519_key_free(key->ed25519key); | |
281 key->ed25519key = m_malloc(sizeof(*key->ed25519key)); | |
282 ret = buf_get_ed25519_pub_key(buf, key->ed25519key); | |
283 if (ret == DROPBEAR_FAILURE) { | |
284 m_free(key->ed25519key); | |
285 key->ed25519key = NULL; | |
286 } | |
287 } | |
288 #endif | |
203 | 289 |
204 TRACE2(("leave buf_get_pub_key")) | 290 TRACE2(("leave buf_get_pub_key")) |
205 | 291 |
206 return ret; | 292 return ret; |
207 } | 293 } |
268 ret = DROPBEAR_SUCCESS; | 354 ret = DROPBEAR_SUCCESS; |
269 } | 355 } |
270 } | 356 } |
271 } | 357 } |
272 #endif | 358 #endif |
359 #if DROPBEAR_ED25519 | |
360 if (keytype == DROPBEAR_SIGNKEY_ED25519) { | |
361 ed25519_key_free(key->ed25519key); | |
362 key->ed25519key = m_malloc(sizeof(*key->ed25519key)); | |
363 ret = buf_get_ed25519_priv_key(buf, key->ed25519key); | |
364 if (ret == DROPBEAR_FAILURE) { | |
365 m_free(key->ed25519key); | |
366 key->ed25519key = NULL; | |
367 } | |
368 } | |
369 #endif | |
273 | 370 |
274 TRACE2(("leave buf_get_priv_key")) | 371 TRACE2(("leave buf_get_priv_key")) |
275 | 372 |
276 return ret; | 373 return ret; |
277 | 374 |
299 if (signkey_is_ecdsa(type)) { | 396 if (signkey_is_ecdsa(type)) { |
300 ecc_key **eck = (ecc_key**)signkey_key_ptr(key, type); | 397 ecc_key **eck = (ecc_key**)signkey_key_ptr(key, type); |
301 if (eck && *eck) { | 398 if (eck && *eck) { |
302 buf_put_ecdsa_pub_key(pubkeys, *eck); | 399 buf_put_ecdsa_pub_key(pubkeys, *eck); |
303 } | 400 } |
401 } | |
402 #endif | |
403 #if DROPBEAR_ED25519 | |
404 if (type == DROPBEAR_SIGNKEY_ED25519) { | |
405 buf_put_ed25519_pub_key(pubkeys, key->ed25519key); | |
304 } | 406 } |
305 #endif | 407 #endif |
306 if (pubkeys->len == 0) { | 408 if (pubkeys->len == 0) { |
307 dropbear_exit("Bad key types in buf_put_pub_key"); | 409 dropbear_exit("Bad key types in buf_put_pub_key"); |
308 } | 410 } |
340 TRACE(("leave buf_put_priv_key: ecdsa done")) | 442 TRACE(("leave buf_put_priv_key: ecdsa done")) |
341 return; | 443 return; |
342 } | 444 } |
343 } | 445 } |
344 #endif | 446 #endif |
447 #if DROPBEAR_ED25519 | |
448 if (type == DROPBEAR_SIGNKEY_ED25519) { | |
449 buf_put_ed25519_priv_key(buf, key->ed25519key); | |
450 TRACE(("leave buf_put_priv_key: ed25519 done")) | |
451 return; | |
452 } | |
453 #endif | |
345 dropbear_exit("Bad key types in put pub key"); | 454 dropbear_exit("Bad key types in put pub key"); |
346 } | 455 } |
347 | 456 |
348 void sign_key_free(sign_key *key) { | 457 void sign_key_free(sign_key *key) { |
349 | 458 |
378 m_free(key->ecckey521); | 487 m_free(key->ecckey521); |
379 key->ecckey521 = NULL; | 488 key->ecckey521 = NULL; |
380 } | 489 } |
381 #endif | 490 #endif |
382 #endif | 491 #endif |
492 #if DROPBEAR_ED25519 | |
493 ed25519_key_free(key->ed25519key); | |
494 key->ed25519key = NULL; | |
495 #endif | |
383 | 496 |
384 m_free(key->filename); | 497 m_free(key->filename); |
385 | 498 |
386 m_free(key); | 499 m_free(key); |
387 TRACE2(("leave sign_key_free")) | 500 TRACE2(("leave sign_key_free")) |
479 #else | 592 #else |
480 return sign_key_sha1_fingerprint(keyblob, keybloblen); | 593 return sign_key_sha1_fingerprint(keyblob, keybloblen); |
481 #endif | 594 #endif |
482 } | 595 } |
483 | 596 |
484 void buf_put_sign(buffer* buf, sign_key *key, enum signkey_type type, | 597 void buf_put_sign(buffer* buf, sign_key *key, enum signature_type sigtype, |
485 const buffer *data_buf) { | 598 const buffer *data_buf) { |
486 buffer *sigblob; | 599 buffer *sigblob = buf_new(MAX_PUBKEY_SIZE); |
487 sigblob = buf_new(MAX_PUBKEY_SIZE); | 600 enum signkey_type keytype = signkey_type_from_signature(sigtype); |
488 | 601 |
489 #if DROPBEAR_DSS | 602 #if DEBUG_TRACE |
490 if (type == DROPBEAR_SIGNKEY_DSS) { | 603 { |
604 const char* signame = signature_name_from_type(sigtype, NULL); | |
605 TRACE(("buf_put_sign type %d %s", sigtype, signame)); | |
606 } | |
607 #endif | |
608 | |
609 | |
610 #if DROPBEAR_DSS | |
611 if (keytype == DROPBEAR_SIGNKEY_DSS) { | |
491 buf_put_dss_sign(sigblob, key->dsskey, data_buf); | 612 buf_put_dss_sign(sigblob, key->dsskey, data_buf); |
492 } | 613 } |
493 #endif | 614 #endif |
494 #if DROPBEAR_RSA | 615 #if DROPBEAR_RSA |
495 if (type == DROPBEAR_SIGNKEY_RSA) { | 616 if (keytype == DROPBEAR_SIGNKEY_RSA) { |
496 buf_put_rsa_sign(sigblob, key->rsakey, data_buf); | 617 buf_put_rsa_sign(sigblob, key->rsakey, sigtype, data_buf); |
497 } | 618 } |
498 #endif | 619 #endif |
499 #if DROPBEAR_ECDSA | 620 #if DROPBEAR_ECDSA |
500 if (signkey_is_ecdsa(type)) { | 621 if (signkey_is_ecdsa(keytype)) { |
501 ecc_key **eck = (ecc_key**)signkey_key_ptr(key, type); | 622 ecc_key **eck = (ecc_key**)signkey_key_ptr(key, keytype); |
502 if (eck && *eck) { | 623 if (eck && *eck) { |
503 buf_put_ecdsa_sign(sigblob, *eck, data_buf); | 624 buf_put_ecdsa_sign(sigblob, *eck, data_buf); |
504 } | 625 } |
626 } | |
627 #endif | |
628 #if DROPBEAR_ED25519 | |
629 if (keytype == DROPBEAR_SIGNKEY_ED25519) { | |
630 buf_put_ed25519_sign(sigblob, key->ed25519key, data_buf); | |
505 } | 631 } |
506 #endif | 632 #endif |
507 if (sigblob->len == 0) { | 633 if (sigblob->len == 0) { |
508 dropbear_exit("Non-matching signing type"); | 634 dropbear_exit("Non-matching signing type"); |
509 } | 635 } |
515 #if DROPBEAR_SIGNKEY_VERIFY | 641 #if DROPBEAR_SIGNKEY_VERIFY |
516 /* Return DROPBEAR_SUCCESS or DROPBEAR_FAILURE. | 642 /* Return DROPBEAR_SUCCESS or DROPBEAR_FAILURE. |
517 * If FAILURE is returned, the position of | 643 * If FAILURE is returned, the position of |
518 * buf is undefined. If SUCCESS is returned, buf will be positioned after the | 644 * buf is undefined. If SUCCESS is returned, buf will be positioned after the |
519 * signature blob */ | 645 * signature blob */ |
520 int buf_verify(buffer * buf, sign_key *key, const buffer *data_buf) { | 646 int buf_verify(buffer * buf, sign_key *key, enum signature_type expect_sigtype, const buffer *data_buf) { |
521 | 647 |
522 char *type_name = NULL; | 648 char *type_name = NULL; |
523 unsigned int type_name_len = 0; | 649 unsigned int type_name_len = 0; |
524 enum signkey_type type; | 650 enum signature_type sigtype; |
651 enum signkey_type keytype; | |
525 | 652 |
526 TRACE(("enter buf_verify")) | 653 TRACE(("enter buf_verify")) |
527 | 654 |
528 buf_getint(buf); /* blob length */ | 655 buf_getint(buf); /* blob length */ |
529 type_name = buf_getstring(buf, &type_name_len); | 656 type_name = buf_getstring(buf, &type_name_len); |
530 type = signkey_type_from_name(type_name, type_name_len); | 657 sigtype = signature_type_from_name(type_name, type_name_len); |
531 m_free(type_name); | 658 m_free(type_name); |
532 | 659 |
533 #if DROPBEAR_DSS | 660 if (expect_sigtype != sigtype) { |
534 if (type == DROPBEAR_SIGNKEY_DSS) { | 661 dropbear_exit("Non-matching signing type"); |
662 } | |
663 | |
664 keytype = signkey_type_from_signature(sigtype); | |
665 #if DROPBEAR_DSS | |
666 if (keytype == DROPBEAR_SIGNKEY_DSS) { | |
535 if (key->dsskey == NULL) { | 667 if (key->dsskey == NULL) { |
536 dropbear_exit("No DSS key to verify signature"); | 668 dropbear_exit("No DSS key to verify signature"); |
537 } | 669 } |
538 return buf_dss_verify(buf, key->dsskey, data_buf); | 670 return buf_dss_verify(buf, key->dsskey, data_buf); |
539 } | 671 } |
540 #endif | 672 #endif |
541 | 673 |
542 #if DROPBEAR_RSA | 674 #if DROPBEAR_RSA |
543 if (type == DROPBEAR_SIGNKEY_RSA) { | 675 if (keytype == DROPBEAR_SIGNKEY_RSA) { |
544 if (key->rsakey == NULL) { | 676 if (key->rsakey == NULL) { |
545 dropbear_exit("No RSA key to verify signature"); | 677 dropbear_exit("No RSA key to verify signature"); |
546 } | 678 } |
547 return buf_rsa_verify(buf, key->rsakey, data_buf); | 679 return buf_rsa_verify(buf, key->rsakey, sigtype, data_buf); |
548 } | 680 } |
549 #endif | 681 #endif |
550 #if DROPBEAR_ECDSA | 682 #if DROPBEAR_ECDSA |
551 if (signkey_is_ecdsa(type)) { | 683 if (signkey_is_ecdsa(keytype)) { |
552 ecc_key **eck = (ecc_key**)signkey_key_ptr(key, type); | 684 ecc_key **eck = (ecc_key**)signkey_key_ptr(key, keytype); |
553 if (eck && *eck) { | 685 if (eck && *eck) { |
554 return buf_ecdsa_verify(buf, *eck, data_buf); | 686 return buf_ecdsa_verify(buf, *eck, data_buf); |
555 } | 687 } |
688 } | |
689 #endif | |
690 #if DROPBEAR_ED25519 | |
691 if (keytype == DROPBEAR_SIGNKEY_ED25519) { | |
692 if (key->ed25519key == NULL) { | |
693 dropbear_exit("No Ed25519 key to verify signature"); | |
694 } | |
695 return buf_ed25519_verify(buf, key->ed25519key, data_buf); | |
556 } | 696 } |
557 #endif | 697 #endif |
558 | 698 |
559 dropbear_exit("Non-matching signing type"); | 699 dropbear_exit("Non-matching signing type"); |
560 return DROPBEAR_FAILURE; | 700 return DROPBEAR_FAILURE; |