comparison signkey.c @ 1855:35d504d59c05

Implement server-side support for sk-ecdsa U2F-backed keys (#142) * Implement server-side support for sk-ecdsa U2F-backed keys * Fix out-of-bounds read on normal ecdsa-sha2-[identifier] keys * Fix one more potential out-of-bounds read * Check if nistp256 curve is used in sk-ecdsa-sha2- key It's the only allowed curve per PROTOCOL.u2f specification * Implement server-side support for sk-ed25519 FIDO2-backed keys * Keys with type sk-* make no sense as host keys, so they should be disabled * fix typo * Make sk-ecdsa call buf_ecdsa_verify This reduces code duplication, the SK code just handles the different message format. * Reduce sk specific code The application id can be stored in signkey, then we don't need to call sk-specific functions from svr-authpubkey * Remove debugging output, which causes compilation errors with DEBUG_TRACE disabled * Proper cleanup of sk_app Co-authored-by: Matt Johnston <[email protected]>
author egor-duda <egor-duda@users.noreply.github.com>
date Sat, 22 Jan 2022 16:53:04 +0300
parents fa6ff07dcc77
children 3f4cdf839a1a
comparison
equal deleted inserted replaced
1854:cba37fe1ddc8 1855:35d504d59c05
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 "sk-ecdsa.h"
32 #include "sk-ed25519.h"
31 #include "rsa.h" 33 #include "rsa.h"
32 #include "dss.h" 34 #include "dss.h"
33 #include "ed25519.h" 35 #include "ed25519.h"
34 36
35 static const char * const signkey_names[DROPBEAR_SIGNKEY_NUM_NAMED] = { 37 static const char * const signkey_names[DROPBEAR_SIGNKEY_NUM_NAMED] = {
41 #endif 43 #endif
42 #if DROPBEAR_ECDSA 44 #if DROPBEAR_ECDSA
43 "ecdsa-sha2-nistp256", 45 "ecdsa-sha2-nistp256",
44 "ecdsa-sha2-nistp384", 46 "ecdsa-sha2-nistp384",
45 "ecdsa-sha2-nistp521", 47 "ecdsa-sha2-nistp521",
48 #if DROPBEAR_SK_ECDSA
49 "[email protected]",
50 #endif /* DROPBEAR_SK_ECDSA */
46 #endif /* DROPBEAR_ECDSA */ 51 #endif /* DROPBEAR_ECDSA */
47 #if DROPBEAR_ED25519 52 #if DROPBEAR_ED25519
48 "ssh-ed25519", 53 "ssh-ed25519",
54 #if DROPBEAR_SK_ED25519
55 "[email protected]",
56 #endif /* DROPBEAR_SK_ED25519 */
49 #endif /* DROPBEAR_ED25519 */ 57 #endif /* DROPBEAR_ED25519 */
50 /* "rsa-sha2-256" is special-cased below since it is only a signature name, not key type */ 58 /* "rsa-sha2-256" is special-cased below since it is only a signature name, not key type */
51 }; 59 };
52 60
53 /* malloc a new sign_key and set the dss and rsa keys to NULL */ 61 /* malloc a new sign_key and set the dss and rsa keys to NULL */
178 void ** 186 void **
179 signkey_key_ptr(sign_key *key, enum signkey_type type) { 187 signkey_key_ptr(sign_key *key, enum signkey_type type) {
180 switch (type) { 188 switch (type) {
181 #if DROPBEAR_ED25519 189 #if DROPBEAR_ED25519
182 case DROPBEAR_SIGNKEY_ED25519: 190 case DROPBEAR_SIGNKEY_ED25519:
191 #if DROPBEAR_SK_ED25519
192 case DROPBEAR_SIGNKEY_SK_ED25519:
193 #endif
183 return (void**)&key->ed25519key; 194 return (void**)&key->ed25519key;
184 #endif 195 #endif
185 #if DROPBEAR_ECDSA 196 #if DROPBEAR_ECDSA
186 #if DROPBEAR_ECC_256 197 #if DROPBEAR_ECC_256
187 case DROPBEAR_SIGNKEY_ECDSA_NISTP256: 198 case DROPBEAR_SIGNKEY_ECDSA_NISTP256:
199 #if DROPBEAR_SK_ECDSA
200 case DROPBEAR_SIGNKEY_SK_ECDSA_NISTP256:
201 #endif
188 return (void**)&key->ecckey256; 202 return (void**)&key->ecckey256;
189 #endif 203 #endif
190 #if DROPBEAR_ECC_384 204 #if DROPBEAR_ECC_384
191 case DROPBEAR_SIGNKEY_ECDSA_NISTP384: 205 case DROPBEAR_SIGNKEY_ECDSA_NISTP384:
192 return (void**)&key->ecckey384; 206 return (void**)&key->ecckey384;
258 key->rsakey = NULL; 272 key->rsakey = NULL;
259 } 273 }
260 } 274 }
261 #endif 275 #endif
262 #if DROPBEAR_ECDSA 276 #if DROPBEAR_ECDSA
263 if (signkey_is_ecdsa(keytype)) { 277 if (signkey_is_ecdsa(keytype)
278 #if DROPBEAR_SK_ECDSA
279 || keytype == DROPBEAR_SIGNKEY_SK_ECDSA_NISTP256
280 #endif
281 ) {
264 ecc_key **eck = (ecc_key**)signkey_key_ptr(key, keytype); 282 ecc_key **eck = (ecc_key**)signkey_key_ptr(key, keytype);
265 if (eck) { 283 if (eck) {
266 if (*eck) { 284 if (*eck) {
267 ecc_free(*eck); 285 ecc_free(*eck);
268 m_free(*eck); 286 m_free(*eck);
274 } 292 }
275 } 293 }
276 } 294 }
277 #endif 295 #endif
278 #if DROPBEAR_ED25519 296 #if DROPBEAR_ED25519
279 if (keytype == DROPBEAR_SIGNKEY_ED25519) { 297 if (keytype == DROPBEAR_SIGNKEY_ED25519
298 #if DROPBEAR_SK_ED25519
299 || keytype == DROPBEAR_SIGNKEY_SK_ED25519
300 #endif
301 ) {
280 ed25519_key_free(key->ed25519key); 302 ed25519_key_free(key->ed25519key);
281 key->ed25519key = m_malloc(sizeof(*key->ed25519key)); 303 key->ed25519key = m_malloc(sizeof(*key->ed25519key));
282 ret = buf_get_ed25519_pub_key(buf, key->ed25519key); 304 ret = buf_get_ed25519_pub_key(buf, key->ed25519key, keytype);
283 if (ret == DROPBEAR_FAILURE) { 305 if (ret == DROPBEAR_FAILURE) {
284 m_free(key->ed25519key); 306 m_free(key->ed25519key);
285 key->ed25519key = NULL; 307 key->ed25519key = NULL;
286 } 308 }
309 }
310 #endif
311
312 #if DROPBEAR_SK_ECDSA || DROPBEAR_SK_ED25519
313 if (0
314 #if DROPBEAR_SK_ED25519
315 || keytype == DROPBEAR_SIGNKEY_SK_ED25519
316 #endif
317 #if DROPBEAR_SK_ECDSA
318 || keytype == DROPBEAR_SIGNKEY_SK_ECDSA_NISTP256
319 #endif
320 ) {
321 key->sk_app = buf_getstring(buf, &key->sk_applen);
287 } 322 }
288 #endif 323 #endif
289 324
290 TRACE2(("leave buf_get_pub_key")) 325 TRACE2(("leave buf_get_pub_key"))
291 326
399 buf_put_ecdsa_pub_key(pubkeys, *eck); 434 buf_put_ecdsa_pub_key(pubkeys, *eck);
400 } 435 }
401 } 436 }
402 #endif 437 #endif
403 #if DROPBEAR_ED25519 438 #if DROPBEAR_ED25519
404 if (type == DROPBEAR_SIGNKEY_ED25519) { 439 if (type == DROPBEAR_SIGNKEY_ED25519
440 #if DROPBEAR_SK_ED25519
441 || type == DROPBEAR_SIGNKEY_SK_ED25519
442 #endif
443 ) {
405 buf_put_ed25519_pub_key(pubkeys, key->ed25519key); 444 buf_put_ed25519_pub_key(pubkeys, key->ed25519key);
406 } 445 }
407 #endif 446 #endif
408 if (pubkeys->len == 0) { 447 if (pubkeys->len == 0) {
409 dropbear_exit("Bad key types in buf_put_pub_key"); 448 dropbear_exit("Bad key types in buf_put_pub_key");
493 ed25519_key_free(key->ed25519key); 532 ed25519_key_free(key->ed25519key);
494 key->ed25519key = NULL; 533 key->ed25519key = NULL;
495 #endif 534 #endif
496 535
497 m_free(key->filename); 536 m_free(key->filename);
537 #if DROPBEAR_SK_ECDSA || DROPBEAR_SK_ED25519
538 if (key->sk_app) {
539 m_free(key->sk_app);
540 }
541 #endif
498 542
499 m_free(key); 543 m_free(key);
500 TRACE2(("leave sign_key_free")) 544 TRACE2(("leave sign_key_free"))
501 } 545 }
502 546
637 buf_free(sigblob); 681 buf_free(sigblob);
638 682
639 } 683 }
640 684
641 #if DROPBEAR_SIGNKEY_VERIFY 685 #if DROPBEAR_SIGNKEY_VERIFY
686
642 /* Return DROPBEAR_SUCCESS or DROPBEAR_FAILURE. 687 /* Return DROPBEAR_SUCCESS or DROPBEAR_FAILURE.
643 * If FAILURE is returned, the position of 688 * If FAILURE is returned, the position of
644 * buf is undefined. If SUCCESS is returned, buf will be positioned after the 689 * buf is undefined. If SUCCESS is returned, buf will be positioned after the
645 * signature blob */ 690 * signature blob */
646 int buf_verify(buffer * buf, sign_key *key, enum signature_type expect_sigtype, const buffer *data_buf) { 691 int buf_verify(buffer * buf, sign_key *key, enum signature_type expect_sigtype, const buffer *data_buf) {
693 dropbear_exit("No Ed25519 key to verify signature"); 738 dropbear_exit("No Ed25519 key to verify signature");
694 } 739 }
695 return buf_ed25519_verify(buf, key->ed25519key, data_buf); 740 return buf_ed25519_verify(buf, key->ed25519key, data_buf);
696 } 741 }
697 #endif 742 #endif
743 #if DROPBEAR_SK_ECDSA
744 if (keytype == DROPBEAR_SIGNKEY_SK_ECDSA_NISTP256) {
745 ecc_key **eck = (ecc_key**)signkey_key_ptr(key, keytype);
746 if (eck && *eck) {
747 return buf_sk_ecdsa_verify(buf, *eck, data_buf, key->sk_app, key->sk_applen);
748 }
749 }
750 #endif
751 #if DROPBEAR_SK_ED25519
752 if (keytype == DROPBEAR_SIGNKEY_SK_ED25519) {
753 dropbear_ed25519_key **eck = (dropbear_ed25519_key**)signkey_key_ptr(key, keytype);
754 if (eck && *eck) {
755 return buf_sk_ed25519_verify(buf, *eck, data_buf, key->sk_app, key->sk_applen);
756 }
757 }
758 #endif
698 759
699 dropbear_exit("Non-matching signing type"); 760 dropbear_exit("Non-matching signing type");
700 return DROPBEAR_FAILURE; 761 return DROPBEAR_FAILURE;
701 } 762 }
702 #endif /* DROPBEAR_SIGNKEY_VERIFY */ 763 #endif /* DROPBEAR_SIGNKEY_VERIFY */