signkey.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779
  1. /*
  2. * Dropbear - a SSH2 server
  3. *
  4. * Copyright (c) 2002,2003 Matt Johnston
  5. * All rights reserved.
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a copy
  8. * of this software and associated documentation files (the "Software"), to deal
  9. * in the Software without restriction, including without limitation the rights
  10. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. * copies of the Software, and to permit persons to whom the Software is
  12. * furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in
  15. * all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  23. * SOFTWARE. */
  24. #include "includes.h"
  25. #include "dbutil.h"
  26. #include "signkey.h"
  27. #include "buffer.h"
  28. #include "ssh.h"
  29. #include "ecdsa.h"
  30. #include "sk-ecdsa.h"
  31. #include "sk-ed25519.h"
  32. #include "rsa.h"
  33. #include "dss.h"
  34. #include "ed25519.h"
  35. static const char * const signkey_names[DROPBEAR_SIGNKEY_NUM_NAMED] = {
  36. #if DROPBEAR_RSA
  37. "ssh-rsa",
  38. #endif
  39. #if DROPBEAR_DSS
  40. "ssh-dss",
  41. #endif
  42. #if DROPBEAR_ECDSA
  43. "ecdsa-sha2-nistp256",
  44. "ecdsa-sha2-nistp384",
  45. "ecdsa-sha2-nistp521",
  46. #if DROPBEAR_SK_ECDSA
  47. "sk-ecdsa-sha2-nistp256@openssh.com",
  48. #endif /* DROPBEAR_SK_ECDSA */
  49. #endif /* DROPBEAR_ECDSA */
  50. #if DROPBEAR_ED25519
  51. "ssh-ed25519",
  52. #if DROPBEAR_SK_ED25519
  53. "sk-ssh-ed25519@openssh.com",
  54. #endif /* DROPBEAR_SK_ED25519 */
  55. #endif /* DROPBEAR_ED25519 */
  56. /* "rsa-sha2-256" is special-cased below since it is only a signature name, not key type */
  57. };
  58. /* malloc a new sign_key and set the dss and rsa keys to NULL */
  59. sign_key * new_sign_key() {
  60. sign_key * ret;
  61. ret = (sign_key*)m_malloc(sizeof(sign_key));
  62. ret->type = DROPBEAR_SIGNKEY_NONE;
  63. ret->source = SIGNKEY_SOURCE_INVALID;
  64. return ret;
  65. }
  66. /* Returns key name corresponding to the type. Exits fatally
  67. * if the type is invalid */
  68. const char* signkey_name_from_type(enum signkey_type type, unsigned int *namelen) {
  69. if (type >= DROPBEAR_SIGNKEY_NUM_NAMED) {
  70. dropbear_exit("Bad key type %d", type);
  71. }
  72. if (namelen) {
  73. *namelen = strlen(signkey_names[type]);
  74. }
  75. return signkey_names[type];
  76. }
  77. /* Returns DROPBEAR_SIGNKEY_NONE if none match */
  78. enum signkey_type signkey_type_from_name(const char* name, unsigned int namelen) {
  79. int i;
  80. for (i = 0; i < DROPBEAR_SIGNKEY_NUM_NAMED; i++) {
  81. const char *fixed_name = signkey_names[i];
  82. if (namelen == strlen(fixed_name)
  83. && memcmp(fixed_name, name, namelen) == 0) {
  84. #if DROPBEAR_ECDSA
  85. /* Some of the ECDSA key sizes are defined even if they're not compiled in */
  86. if (0
  87. #if !DROPBEAR_ECC_256
  88. || i == DROPBEAR_SIGNKEY_ECDSA_NISTP256
  89. #endif
  90. #if !DROPBEAR_ECC_384
  91. || i == DROPBEAR_SIGNKEY_ECDSA_NISTP384
  92. #endif
  93. #if !DROPBEAR_ECC_521
  94. || i == DROPBEAR_SIGNKEY_ECDSA_NISTP521
  95. #endif
  96. ) {
  97. TRACE(("attempt to use ecdsa type %d not compiled in", i))
  98. return DROPBEAR_SIGNKEY_NONE;
  99. }
  100. #endif
  101. return (enum signkey_type)i;
  102. }
  103. }
  104. TRACE(("signkey_type_from_name unexpected key type."))
  105. return DROPBEAR_SIGNKEY_NONE;
  106. }
  107. /* Special case for rsa-sha2-256. This could be generalised if more
  108. signature names are added that aren't 1-1 with public key names */
  109. const char* signature_name_from_type(enum signature_type type, unsigned int *namelen) {
  110. #if DROPBEAR_RSA_SHA256
  111. if (type == DROPBEAR_SIGNATURE_RSA_SHA256) {
  112. if (namelen) {
  113. *namelen = strlen(SSH_SIGNATURE_RSA_SHA256);
  114. }
  115. return SSH_SIGNATURE_RSA_SHA256;
  116. }
  117. #endif
  118. #if DROPBEAR_RSA_SHA1
  119. if (type == DROPBEAR_SIGNATURE_RSA_SHA1) {
  120. if (namelen) {
  121. *namelen = strlen(SSH_SIGNKEY_RSA);
  122. }
  123. return SSH_SIGNKEY_RSA;
  124. }
  125. #endif
  126. return signkey_name_from_type((enum signkey_type)type, namelen);
  127. }
  128. /* Returns DROPBEAR_SIGNATURE_NONE if none match */
  129. enum signature_type signature_type_from_name(const char* name, unsigned int namelen) {
  130. #if DROPBEAR_RSA_SHA256
  131. if (namelen == strlen(SSH_SIGNATURE_RSA_SHA256)
  132. && memcmp(name, SSH_SIGNATURE_RSA_SHA256, namelen) == 0) {
  133. return DROPBEAR_SIGNATURE_RSA_SHA256;
  134. }
  135. #endif
  136. #if DROPBEAR_RSA_SHA1
  137. if (namelen == strlen(SSH_SIGNKEY_RSA)
  138. && memcmp(name, SSH_SIGNKEY_RSA, namelen) == 0) {
  139. return DROPBEAR_SIGNATURE_RSA_SHA1;
  140. }
  141. #endif
  142. return (enum signature_type)signkey_type_from_name(name, namelen);
  143. }
  144. /* Returns the signature type from a key type. Must not be called
  145. with RSA keytype */
  146. enum signature_type signature_type_from_signkey(enum signkey_type keytype) {
  147. #if DROPBEAR_RSA
  148. assert(keytype != DROPBEAR_SIGNKEY_RSA);
  149. #endif
  150. assert(keytype < DROPBEAR_SIGNKEY_NUM_NAMED);
  151. return (enum signature_type)keytype;
  152. }
  153. enum signkey_type signkey_type_from_signature(enum signature_type sigtype) {
  154. #if DROPBEAR_RSA_SHA256
  155. if (sigtype == DROPBEAR_SIGNATURE_RSA_SHA256) {
  156. return DROPBEAR_SIGNKEY_RSA;
  157. }
  158. #endif
  159. #if DROPBEAR_RSA_SHA1
  160. if (sigtype == DROPBEAR_SIGNATURE_RSA_SHA1) {
  161. return DROPBEAR_SIGNKEY_RSA;
  162. }
  163. #endif
  164. assert((int)sigtype < (int)DROPBEAR_SIGNKEY_NUM_NAMED);
  165. return (enum signkey_type)sigtype;
  166. }
  167. /* Returns a pointer to the key part specific to "type".
  168. Be sure to check both (ret != NULL) and (*ret != NULL) */
  169. void **
  170. signkey_key_ptr(sign_key *key, enum signkey_type type) {
  171. switch (type) {
  172. #if DROPBEAR_ED25519
  173. case DROPBEAR_SIGNKEY_ED25519:
  174. #if DROPBEAR_SK_ED25519
  175. case DROPBEAR_SIGNKEY_SK_ED25519:
  176. #endif
  177. return (void**)&key->ed25519key;
  178. #endif
  179. #if DROPBEAR_ECDSA
  180. #if DROPBEAR_ECC_256
  181. case DROPBEAR_SIGNKEY_ECDSA_NISTP256:
  182. #if DROPBEAR_SK_ECDSA
  183. case DROPBEAR_SIGNKEY_SK_ECDSA_NISTP256:
  184. #endif
  185. return (void**)&key->ecckey256;
  186. #endif
  187. #if DROPBEAR_ECC_384
  188. case DROPBEAR_SIGNKEY_ECDSA_NISTP384:
  189. return (void**)&key->ecckey384;
  190. #endif
  191. #if DROPBEAR_ECC_521
  192. case DROPBEAR_SIGNKEY_ECDSA_NISTP521:
  193. return (void**)&key->ecckey521;
  194. #endif
  195. #endif /* DROPBEAR_ECDSA */
  196. #if DROPBEAR_RSA
  197. case DROPBEAR_SIGNKEY_RSA:
  198. return (void**)&key->rsakey;
  199. #endif
  200. #if DROPBEAR_DSS
  201. case DROPBEAR_SIGNKEY_DSS:
  202. return (void**)&key->dsskey;
  203. #endif
  204. default:
  205. return NULL;
  206. }
  207. }
  208. /* returns DROPBEAR_SUCCESS on success, DROPBEAR_FAILURE on fail.
  209. * type should be set by the caller to specify the type to read, and
  210. * on return is set to the type read (useful when type = _ANY) */
  211. int buf_get_pub_key(buffer *buf, sign_key *key, enum signkey_type *type) {
  212. char *ident;
  213. unsigned int len;
  214. enum signkey_type keytype;
  215. int ret = DROPBEAR_FAILURE;
  216. TRACE2(("enter buf_get_pub_key"))
  217. ident = buf_getstring(buf, &len);
  218. keytype = signkey_type_from_name(ident, len);
  219. m_free(ident);
  220. if (*type != DROPBEAR_SIGNKEY_ANY && *type != keytype) {
  221. TRACE(("buf_get_pub_key bad type - got %d, expected %d", keytype, *type))
  222. return DROPBEAR_FAILURE;
  223. }
  224. TRACE2(("buf_get_pub_key keytype is %d", keytype))
  225. *type = keytype;
  226. /* Rewind the buffer back before "ssh-rsa" etc */
  227. buf_decrpos(buf, len + 4);
  228. #if DROPBEAR_DSS
  229. if (keytype == DROPBEAR_SIGNKEY_DSS) {
  230. dss_key_free(key->dsskey);
  231. key->dsskey = m_malloc(sizeof(*key->dsskey));
  232. ret = buf_get_dss_pub_key(buf, key->dsskey);
  233. if (ret == DROPBEAR_FAILURE) {
  234. dss_key_free(key->dsskey);
  235. key->dsskey = NULL;
  236. }
  237. }
  238. #endif
  239. #if DROPBEAR_RSA
  240. if (keytype == DROPBEAR_SIGNKEY_RSA) {
  241. rsa_key_free(key->rsakey);
  242. key->rsakey = m_malloc(sizeof(*key->rsakey));
  243. ret = buf_get_rsa_pub_key(buf, key->rsakey);
  244. if (ret == DROPBEAR_FAILURE) {
  245. rsa_key_free(key->rsakey);
  246. key->rsakey = NULL;
  247. }
  248. }
  249. #endif
  250. #if DROPBEAR_ECDSA
  251. if (signkey_is_ecdsa(keytype)
  252. #if DROPBEAR_SK_ECDSA
  253. || keytype == DROPBEAR_SIGNKEY_SK_ECDSA_NISTP256
  254. #endif
  255. ) {
  256. ecc_key **eck = (ecc_key**)signkey_key_ptr(key, keytype);
  257. if (eck) {
  258. if (*eck) {
  259. ecc_free(*eck);
  260. m_free(*eck);
  261. *eck = NULL;
  262. }
  263. *eck = buf_get_ecdsa_pub_key(buf);
  264. if (*eck) {
  265. ret = DROPBEAR_SUCCESS;
  266. }
  267. }
  268. }
  269. #endif
  270. #if DROPBEAR_ED25519
  271. if (keytype == DROPBEAR_SIGNKEY_ED25519
  272. #if DROPBEAR_SK_ED25519
  273. || keytype == DROPBEAR_SIGNKEY_SK_ED25519
  274. #endif
  275. ) {
  276. ed25519_key_free(key->ed25519key);
  277. key->ed25519key = m_malloc(sizeof(*key->ed25519key));
  278. ret = buf_get_ed25519_pub_key(buf, key->ed25519key, keytype);
  279. if (ret == DROPBEAR_FAILURE) {
  280. m_free(key->ed25519key);
  281. key->ed25519key = NULL;
  282. }
  283. }
  284. #endif
  285. #if DROPBEAR_SK_ECDSA || DROPBEAR_SK_ED25519
  286. if (0
  287. #if DROPBEAR_SK_ED25519
  288. || keytype == DROPBEAR_SIGNKEY_SK_ED25519
  289. #endif
  290. #if DROPBEAR_SK_ECDSA
  291. || keytype == DROPBEAR_SIGNKEY_SK_ECDSA_NISTP256
  292. #endif
  293. ) {
  294. key->sk_app = buf_getstring(buf, &key->sk_applen);
  295. }
  296. #endif
  297. TRACE2(("leave buf_get_pub_key"))
  298. return ret;
  299. }
  300. /* returns DROPBEAR_SUCCESS on success, DROPBEAR_FAILURE on fail.
  301. * type should be set by the caller to specify the type to read, and
  302. * on return is set to the type read (useful when type = _ANY) */
  303. int buf_get_priv_key(buffer *buf, sign_key *key, enum signkey_type *type) {
  304. char *ident;
  305. unsigned int len;
  306. enum signkey_type keytype;
  307. int ret = DROPBEAR_FAILURE;
  308. TRACE2(("enter buf_get_priv_key"))
  309. ident = buf_getstring(buf, &len);
  310. keytype = signkey_type_from_name(ident, len);
  311. m_free(ident);
  312. if (*type != DROPBEAR_SIGNKEY_ANY && *type != keytype) {
  313. TRACE(("wrong key type: %d %d", *type, keytype))
  314. return DROPBEAR_FAILURE;
  315. }
  316. *type = keytype;
  317. /* Rewind the buffer back before "ssh-rsa" etc */
  318. buf_decrpos(buf, len + 4);
  319. #if DROPBEAR_DSS
  320. if (keytype == DROPBEAR_SIGNKEY_DSS) {
  321. dss_key_free(key->dsskey);
  322. key->dsskey = m_malloc(sizeof(*key->dsskey));
  323. ret = buf_get_dss_priv_key(buf, key->dsskey);
  324. if (ret == DROPBEAR_FAILURE) {
  325. dss_key_free(key->dsskey);
  326. key->dsskey = NULL;
  327. }
  328. }
  329. #endif
  330. #if DROPBEAR_RSA
  331. if (keytype == DROPBEAR_SIGNKEY_RSA) {
  332. rsa_key_free(key->rsakey);
  333. key->rsakey = m_malloc(sizeof(*key->rsakey));
  334. ret = buf_get_rsa_priv_key(buf, key->rsakey);
  335. if (ret == DROPBEAR_FAILURE) {
  336. rsa_key_free(key->rsakey);
  337. key->rsakey = NULL;
  338. }
  339. }
  340. #endif
  341. #if DROPBEAR_ECDSA
  342. if (signkey_is_ecdsa(keytype)) {
  343. ecc_key **eck = (ecc_key**)signkey_key_ptr(key, keytype);
  344. if (eck) {
  345. if (*eck) {
  346. ecc_free(*eck);
  347. m_free(*eck);
  348. *eck = NULL;
  349. }
  350. *eck = buf_get_ecdsa_priv_key(buf);
  351. if (*eck) {
  352. ret = DROPBEAR_SUCCESS;
  353. }
  354. }
  355. }
  356. #endif
  357. #if DROPBEAR_ED25519
  358. if (keytype == DROPBEAR_SIGNKEY_ED25519) {
  359. ed25519_key_free(key->ed25519key);
  360. key->ed25519key = m_malloc(sizeof(*key->ed25519key));
  361. ret = buf_get_ed25519_priv_key(buf, key->ed25519key);
  362. if (ret == DROPBEAR_FAILURE) {
  363. m_free(key->ed25519key);
  364. key->ed25519key = NULL;
  365. }
  366. }
  367. #endif
  368. TRACE2(("leave buf_get_priv_key"))
  369. return ret;
  370. }
  371. /* type is either DROPBEAR_SIGNKEY_DSS or DROPBEAR_SIGNKEY_RSA */
  372. void buf_put_pub_key(buffer* buf, sign_key *key, enum signkey_type type) {
  373. buffer *pubkeys;
  374. TRACE2(("enter buf_put_pub_key"))
  375. pubkeys = buf_new(MAX_PUBKEY_SIZE);
  376. #if DROPBEAR_DSS
  377. if (type == DROPBEAR_SIGNKEY_DSS) {
  378. buf_put_dss_pub_key(pubkeys, key->dsskey);
  379. }
  380. #endif
  381. #if DROPBEAR_RSA
  382. if (type == DROPBEAR_SIGNKEY_RSA) {
  383. buf_put_rsa_pub_key(pubkeys, key->rsakey);
  384. }
  385. #endif
  386. #if DROPBEAR_ECDSA
  387. if (signkey_is_ecdsa(type)) {
  388. ecc_key **eck = (ecc_key**)signkey_key_ptr(key, type);
  389. if (eck && *eck) {
  390. buf_put_ecdsa_pub_key(pubkeys, *eck);
  391. }
  392. }
  393. #endif
  394. #if DROPBEAR_ED25519
  395. if (type == DROPBEAR_SIGNKEY_ED25519
  396. #if DROPBEAR_SK_ED25519
  397. || type == DROPBEAR_SIGNKEY_SK_ED25519
  398. #endif
  399. ) {
  400. buf_put_ed25519_pub_key(pubkeys, key->ed25519key);
  401. }
  402. #endif
  403. if (pubkeys->len == 0) {
  404. dropbear_exit("Bad key types in buf_put_pub_key");
  405. }
  406. buf_putbufstring(buf, pubkeys);
  407. buf_free(pubkeys);
  408. TRACE2(("leave buf_put_pub_key"))
  409. }
  410. /* type is either DROPBEAR_SIGNKEY_DSS or DROPBEAR_SIGNKEY_RSA */
  411. void buf_put_priv_key(buffer* buf, sign_key *key, enum signkey_type type) {
  412. TRACE(("enter buf_put_priv_key"))
  413. TRACE(("type is %d", type))
  414. #if DROPBEAR_DSS
  415. if (type == DROPBEAR_SIGNKEY_DSS) {
  416. buf_put_dss_priv_key(buf, key->dsskey);
  417. TRACE(("leave buf_put_priv_key: dss done"))
  418. return;
  419. }
  420. #endif
  421. #if DROPBEAR_RSA
  422. if (type == DROPBEAR_SIGNKEY_RSA) {
  423. buf_put_rsa_priv_key(buf, key->rsakey);
  424. TRACE(("leave buf_put_priv_key: rsa done"))
  425. return;
  426. }
  427. #endif
  428. #if DROPBEAR_ECDSA
  429. if (signkey_is_ecdsa(type)) {
  430. ecc_key **eck = (ecc_key**)signkey_key_ptr(key, type);
  431. if (eck && *eck) {
  432. buf_put_ecdsa_priv_key(buf, *eck);
  433. TRACE(("leave buf_put_priv_key: ecdsa done"))
  434. return;
  435. }
  436. }
  437. #endif
  438. #if DROPBEAR_ED25519
  439. if (type == DROPBEAR_SIGNKEY_ED25519) {
  440. buf_put_ed25519_priv_key(buf, key->ed25519key);
  441. TRACE(("leave buf_put_priv_key: ed25519 done"))
  442. return;
  443. }
  444. #endif
  445. dropbear_exit("Bad key types in put pub key");
  446. }
  447. void sign_key_free(sign_key *key) {
  448. TRACE2(("enter sign_key_free"))
  449. #if DROPBEAR_DSS
  450. dss_key_free(key->dsskey);
  451. key->dsskey = NULL;
  452. #endif
  453. #if DROPBEAR_RSA
  454. rsa_key_free(key->rsakey);
  455. key->rsakey = NULL;
  456. #endif
  457. #if DROPBEAR_ECDSA
  458. #if DROPBEAR_ECC_256
  459. if (key->ecckey256) {
  460. ecc_free(key->ecckey256);
  461. m_free(key->ecckey256);
  462. key->ecckey256 = NULL;
  463. }
  464. #endif
  465. #if DROPBEAR_ECC_384
  466. if (key->ecckey384) {
  467. ecc_free(key->ecckey384);
  468. m_free(key->ecckey384);
  469. key->ecckey384 = NULL;
  470. }
  471. #endif
  472. #if DROPBEAR_ECC_521
  473. if (key->ecckey521) {
  474. ecc_free(key->ecckey521);
  475. m_free(key->ecckey521);
  476. key->ecckey521 = NULL;
  477. }
  478. #endif
  479. #endif
  480. #if DROPBEAR_ED25519
  481. ed25519_key_free(key->ed25519key);
  482. key->ed25519key = NULL;
  483. #endif
  484. m_free(key->filename);
  485. #if DROPBEAR_SK_ECDSA || DROPBEAR_SK_ED25519
  486. if (key->sk_app) {
  487. m_free(key->sk_app);
  488. }
  489. #endif
  490. m_free(key);
  491. TRACE2(("leave sign_key_free"))
  492. }
  493. static char * sign_key_sha256_fingerprint(const unsigned char* keyblob,
  494. unsigned int keybloblen) {
  495. char * ret;
  496. hash_state hs;
  497. unsigned char hash[SHA256_HASH_SIZE];
  498. unsigned int b64chars, start;
  499. unsigned long b64size;
  500. const char *prefix = "SHA256:";
  501. int err;
  502. sha256_init(&hs);
  503. sha256_process(&hs, keyblob, keybloblen);
  504. sha256_done(&hs, hash);
  505. /* eg "SHA256:P9szN0L2ls6KxkVv7Bppv3asnZCn03rY7Msm/c8+ZgA"
  506. * 256/6 = 42.66 => 43 base64 chars. OpenSSH discards
  507. * base64 padding output. */
  508. start = strlen(prefix);
  509. b64chars = 43;
  510. /* space for discarded b64 padding and null terminator */
  511. b64size = b64chars + 4;
  512. ret = m_malloc(start + b64size);
  513. memcpy(ret, prefix, start);
  514. err = base64_encode(hash, SHA256_HASH_SIZE, &ret[start], &b64size);
  515. if (err != CRYPT_OK) {
  516. dropbear_exit("base64 failed");
  517. }
  518. ret[start + b64chars] = '\0';
  519. return ret;
  520. }
  521. /* This will return a freshly malloced string */
  522. char * sign_key_fingerprint(const unsigned char* keyblob, unsigned int keybloblen) {
  523. return sign_key_sha256_fingerprint(keyblob, keybloblen);
  524. }
  525. void buf_put_sign(buffer* buf, sign_key *key, enum signature_type sigtype,
  526. const buffer *data_buf) {
  527. buffer *sigblob = buf_new(MAX_PUBKEY_SIZE);
  528. enum signkey_type keytype = signkey_type_from_signature(sigtype);
  529. #if DEBUG_TRACE
  530. {
  531. const char* signame = signature_name_from_type(sigtype, NULL);
  532. TRACE(("buf_put_sign type %d %s", sigtype, signame));
  533. }
  534. #endif
  535. #if DROPBEAR_DSS
  536. if (keytype == DROPBEAR_SIGNKEY_DSS) {
  537. buf_put_dss_sign(sigblob, key->dsskey, data_buf);
  538. }
  539. #endif
  540. #if DROPBEAR_RSA
  541. if (keytype == DROPBEAR_SIGNKEY_RSA) {
  542. buf_put_rsa_sign(sigblob, key->rsakey, sigtype, data_buf);
  543. }
  544. #endif
  545. #if DROPBEAR_ECDSA
  546. if (signkey_is_ecdsa(keytype)) {
  547. ecc_key **eck = (ecc_key**)signkey_key_ptr(key, keytype);
  548. if (eck && *eck) {
  549. buf_put_ecdsa_sign(sigblob, *eck, data_buf);
  550. }
  551. }
  552. #endif
  553. #if DROPBEAR_ED25519
  554. if (keytype == DROPBEAR_SIGNKEY_ED25519) {
  555. buf_put_ed25519_sign(sigblob, key->ed25519key, data_buf);
  556. }
  557. #endif
  558. if (sigblob->len == 0) {
  559. dropbear_exit("Non-matching signing type");
  560. }
  561. buf_putbufstring(buf, sigblob);
  562. buf_free(sigblob);
  563. }
  564. #if DROPBEAR_SIGNKEY_VERIFY
  565. /* Return DROPBEAR_SUCCESS or DROPBEAR_FAILURE.
  566. * If FAILURE is returned, the position of
  567. * buf is undefined. If SUCCESS is returned, buf will be positioned after the
  568. * signature blob */
  569. int buf_verify(buffer * buf, sign_key *key, enum signature_type expect_sigtype, const buffer *data_buf) {
  570. char *type_name = NULL;
  571. unsigned int type_name_len = 0;
  572. enum signature_type sigtype;
  573. enum signkey_type keytype;
  574. TRACE(("enter buf_verify"))
  575. buf_getint(buf); /* blob length */
  576. type_name = buf_getstring(buf, &type_name_len);
  577. sigtype = signature_type_from_name(type_name, type_name_len);
  578. m_free(type_name);
  579. if (expect_sigtype != sigtype) {
  580. dropbear_exit("Non-matching signing type");
  581. }
  582. keytype = signkey_type_from_signature(sigtype);
  583. #if DROPBEAR_DSS
  584. if (keytype == DROPBEAR_SIGNKEY_DSS) {
  585. if (key->dsskey == NULL) {
  586. dropbear_exit("No DSS key to verify signature");
  587. }
  588. return buf_dss_verify(buf, key->dsskey, data_buf);
  589. }
  590. #endif
  591. #if DROPBEAR_RSA
  592. if (keytype == DROPBEAR_SIGNKEY_RSA) {
  593. if (key->rsakey == NULL) {
  594. dropbear_exit("No RSA key to verify signature");
  595. }
  596. return buf_rsa_verify(buf, key->rsakey, sigtype, data_buf);
  597. }
  598. #endif
  599. #if DROPBEAR_ECDSA
  600. if (signkey_is_ecdsa(keytype)) {
  601. ecc_key **eck = (ecc_key**)signkey_key_ptr(key, keytype);
  602. if (eck && *eck) {
  603. return buf_ecdsa_verify(buf, *eck, data_buf);
  604. }
  605. }
  606. #endif
  607. #if DROPBEAR_ED25519
  608. if (keytype == DROPBEAR_SIGNKEY_ED25519) {
  609. if (key->ed25519key == NULL) {
  610. dropbear_exit("No Ed25519 key to verify signature");
  611. }
  612. return buf_ed25519_verify(buf, key->ed25519key, data_buf);
  613. }
  614. #endif
  615. #if DROPBEAR_SK_ECDSA
  616. if (keytype == DROPBEAR_SIGNKEY_SK_ECDSA_NISTP256) {
  617. ecc_key **eck = (ecc_key**)signkey_key_ptr(key, keytype);
  618. if (eck && *eck) {
  619. return buf_sk_ecdsa_verify(buf, *eck, data_buf, key->sk_app, key->sk_applen);
  620. }
  621. }
  622. #endif
  623. #if DROPBEAR_SK_ED25519
  624. if (keytype == DROPBEAR_SIGNKEY_SK_ED25519) {
  625. dropbear_ed25519_key **eck = (dropbear_ed25519_key**)signkey_key_ptr(key, keytype);
  626. if (eck && *eck) {
  627. return buf_sk_ed25519_verify(buf, *eck, data_buf, key->sk_app, key->sk_applen);
  628. }
  629. }
  630. #endif
  631. dropbear_exit("Non-matching signing type");
  632. return DROPBEAR_FAILURE;
  633. }
  634. #endif /* DROPBEAR_SIGNKEY_VERIFY */
  635. #if DROPBEAR_KEY_LINES /* ie we're using authorized_keys or known_hosts */
  636. /* Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE when given a buffer containing
  637. * a key, a key, and a type. The buffer is positioned at the start of the
  638. * base64 data, and contains no trailing data */
  639. /* If fingerprint is non-NULL, it will be set to a malloc()ed fingerprint
  640. of the key if it is successfully decoded */
  641. int cmp_base64_key(const unsigned char* keyblob, unsigned int keybloblen,
  642. const unsigned char* algoname, unsigned int algolen,
  643. const buffer * line, char ** fingerprint) {
  644. buffer * decodekey = NULL;
  645. int ret = DROPBEAR_FAILURE;
  646. unsigned int len, filealgolen;
  647. unsigned long decodekeylen;
  648. unsigned char* filealgo = NULL;
  649. /* now we have the actual data */
  650. len = line->len - line->pos;
  651. if (len == 0) {
  652. /* base64_decode doesn't like NULL argument */
  653. return DROPBEAR_FAILURE;
  654. }
  655. decodekeylen = len * 2; /* big to be safe */
  656. decodekey = buf_new(decodekeylen);
  657. if (base64_decode(buf_getptr(line, len), len,
  658. buf_getwriteptr(decodekey, decodekey->size),
  659. &decodekeylen) != CRYPT_OK) {
  660. TRACE(("checkpubkey: base64 decode failed"))
  661. goto out;
  662. }
  663. TRACE(("checkpubkey: base64_decode success"))
  664. buf_incrlen(decodekey, decodekeylen);
  665. if (fingerprint) {
  666. *fingerprint = sign_key_fingerprint(buf_getptr(decodekey, decodekeylen),
  667. decodekeylen);
  668. }
  669. /* compare the keys */
  670. if ( ( decodekeylen != keybloblen )
  671. || memcmp( buf_getptr(decodekey, decodekey->len),
  672. keyblob, decodekey->len) != 0) {
  673. TRACE(("checkpubkey: compare failed"))
  674. goto out;
  675. }
  676. /* ... and also check that the algo specified and the algo in the key
  677. * itself match */
  678. filealgolen = buf_getint(decodekey);
  679. filealgo = buf_getptr(decodekey, filealgolen);
  680. if (filealgolen != algolen || memcmp(filealgo, algoname, algolen) != 0) {
  681. TRACE(("checkpubkey: algo match failed"))
  682. goto out;
  683. }
  684. /* All checks passed */
  685. ret = DROPBEAR_SUCCESS;
  686. out:
  687. buf_free(decodekey);
  688. decodekey = NULL;
  689. return ret;
  690. }
  691. #endif
  692. #if DROPBEAR_FUZZ
  693. const char * const * fuzz_signkey_names = signkey_names;
  694. #endif