signkey_ossh.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. #include "includes.h"
  2. #include "dbutil.h"
  3. #include "ssh.h"
  4. #include "signkey_ossh.h"
  5. #include "bignum.h"
  6. #include "ecdsa.h"
  7. #include "sk-ecdsa.h"
  8. #include "sk-ed25519.h"
  9. #include "rsa.h"
  10. #include "dss.h"
  11. #include "ed25519.h"
  12. #if DROPBEAR_RSA
  13. /* OpenSSH raw private RSA format is
  14. string "ssh-rsa"
  15. mpint n
  16. mpint e
  17. mpint d
  18. mpint iqmp (q^-1) mod p
  19. mpint p
  20. mpint q
  21. */
  22. void buf_put_rsa_priv_ossh(buffer *buf, const sign_key *akey) {
  23. const dropbear_rsa_key *key = akey->rsakey;
  24. mp_int iqmp;
  25. dropbear_assert(key != NULL);
  26. if (!(key->p && key->q)) {
  27. dropbear_exit("Pre-0.33 Dropbear keys cannot be converted to OpenSSH keys.\n");
  28. }
  29. m_mp_init(&iqmp);
  30. /* iqmp = (q^-1) mod p */
  31. if (mp_invmod(key->q, key->p, &iqmp) != MP_OKAY) {
  32. dropbear_exit("Bignum error for iqmp\n");
  33. }
  34. buf_putstring(buf, SSH_SIGNKEY_RSA, SSH_SIGNKEY_RSA_LEN);
  35. buf_putmpint(buf, key->n);
  36. buf_putmpint(buf, key->e);
  37. buf_putmpint(buf, key->d);
  38. buf_putmpint(buf, &iqmp);
  39. buf_putmpint(buf, key->p);
  40. buf_putmpint(buf, key->q);
  41. mp_clear(&iqmp);
  42. }
  43. int buf_get_rsa_priv_ossh(buffer *buf, sign_key *akey) {
  44. int ret = DROPBEAR_FAILURE;
  45. dropbear_rsa_key *key = NULL;
  46. mp_int iqmp;
  47. rsa_key_free(akey->rsakey);
  48. akey->rsakey = m_malloc(sizeof(*akey->rsakey));
  49. key = akey->rsakey;
  50. m_mp_alloc_init_multi(&key->e, &key->n, &key->d, &key->p, &key->q, NULL);
  51. buf_eatstring(buf);
  52. m_mp_init(&iqmp);
  53. if (buf_getmpint(buf, key->n) == DROPBEAR_SUCCESS
  54. && buf_getmpint(buf, key->e) == DROPBEAR_SUCCESS
  55. && buf_getmpint(buf, key->d) == DROPBEAR_SUCCESS
  56. && buf_getmpint(buf, &iqmp) == DROPBEAR_SUCCESS
  57. && buf_getmpint(buf, key->p) == DROPBEAR_SUCCESS
  58. && buf_getmpint(buf, key->q) == DROPBEAR_SUCCESS) {
  59. ret = DROPBEAR_SUCCESS;
  60. }
  61. mp_clear(&iqmp);
  62. return ret;
  63. }
  64. #endif /* DROPBEAR_RSA */
  65. #if DROPBEAR_ED25519
  66. /* OpenSSH raw private ed25519 format is
  67. string "ssh-ed25519"
  68. uint32 32
  69. byte[32] pubkey
  70. uint32 64
  71. byte[32] privkey
  72. byte[32] pubkey
  73. */
  74. void buf_put_ed25519_priv_ossh(buffer *buf, const sign_key *akey) {
  75. const dropbear_ed25519_key *key = akey->ed25519key;
  76. dropbear_assert(key != NULL);
  77. buf_putstring(buf, SSH_SIGNKEY_ED25519, SSH_SIGNKEY_ED25519_LEN);
  78. buf_putint(buf, CURVE25519_LEN);
  79. buf_putbytes(buf, key->pub, CURVE25519_LEN);
  80. buf_putint(buf, CURVE25519_LEN*2);
  81. buf_putbytes(buf, key->priv, CURVE25519_LEN);
  82. buf_putbytes(buf, key->pub, CURVE25519_LEN);
  83. }
  84. int buf_get_ed25519_priv_ossh(buffer *buf, sign_key *akey) {
  85. dropbear_ed25519_key *key = NULL;
  86. uint32_t len;
  87. ed25519_key_free(akey->ed25519key);
  88. akey->ed25519key = m_malloc(sizeof(*akey->ed25519key));
  89. key = akey->ed25519key;
  90. /* Parse past the first string and pubkey */
  91. if (buf_get_ed25519_pub_key(buf, key, DROPBEAR_SIGNKEY_ED25519)
  92. == DROPBEAR_FAILURE) {
  93. dropbear_log(LOG_ERR, "Error parsing ed25519 key, pubkey");
  94. return DROPBEAR_FAILURE;
  95. }
  96. len = buf_getint(buf);
  97. if (len != 2*CURVE25519_LEN) {
  98. dropbear_log(LOG_ERR, "Error parsing ed25519 key, bad length");
  99. return DROPBEAR_FAILURE;
  100. }
  101. memcpy(key->priv, buf_getptr(buf, CURVE25519_LEN), CURVE25519_LEN);
  102. buf_incrpos(buf, CURVE25519_LEN);
  103. /* Sanity check */
  104. if (memcmp(buf_getptr(buf, CURVE25519_LEN), key->pub,
  105. CURVE25519_LEN) != 0) {
  106. dropbear_log(LOG_ERR, "Error parsing ed25519 key, mismatch pubkey");
  107. return DROPBEAR_FAILURE;
  108. }
  109. return DROPBEAR_SUCCESS;
  110. }
  111. #endif /* DROPBEAR_ED255219 */
  112. #if DROPBEAR_ECDSA
  113. /* OpenSSH raw private ecdsa format is the same as Dropbear's.
  114. # First part is the same as the SSH wire pubkey format
  115. string "ecdsa-sha2-[identifier]"
  116. string [identifier]
  117. string Q
  118. # With private part appended
  119. mpint d
  120. */
  121. void buf_put_ecdsa_priv_ossh(buffer *buf, const sign_key *key) {
  122. ecc_key **eck = (ecc_key**)signkey_key_ptr((sign_key*)key, key->type);
  123. if (eck && *eck) {
  124. buf_put_ecdsa_priv_key(buf, *eck);
  125. return;
  126. }
  127. dropbear_exit("ecdsa key is not set");
  128. }
  129. int buf_get_ecdsa_priv_ossh(buffer *buf, sign_key *key) {
  130. ecc_key **eck = (ecc_key**)signkey_key_ptr(key, key->type);
  131. if (eck) {
  132. if (*eck) {
  133. ecc_free(*eck);
  134. m_free(*eck);
  135. *eck = NULL;
  136. }
  137. *eck = buf_get_ecdsa_priv_key(buf);
  138. if (*eck) {
  139. return DROPBEAR_SUCCESS;
  140. }
  141. }
  142. return DROPBEAR_FAILURE;
  143. }
  144. #endif /* DROPBEAR_ECDSA */