dropbear/signkey_ossh.c

126 lines
3.3 KiB
C
Raw Normal View History

#include "includes.h"
#include "dbutil.h"
#include "ssh.h"
#include "signkey_ossh.h"
#include "bignum.h"
#include "ecdsa.h"
#include "sk-ecdsa.h"
#include "sk-ed25519.h"
#include "rsa.h"
#include "dss.h"
#include "ed25519.h"
#if DROPBEAR_RSA
/* OpenSSH raw private RSA format is
string "ssh-rsa"
mpint n
mpint e
mpint d
mpint iqmp (q^-1) mod p
mpint p
mpint q
*/
void buf_put_rsa_priv_ossh(buffer *buf, const sign_key *akey) {
const dropbear_rsa_key *key = akey->rsakey;
mp_int iqmp;
dropbear_assert(key != NULL);
if (!(key->p && key->q)) {
dropbear_exit("Pre-0.33 Dropbear keys cannot be converted to OpenSSH keys.\n");
}
m_mp_init(&iqmp);
/* iqmp = (q^-1) mod p */
if (mp_invmod(key->q, key->p, &iqmp) != MP_OKAY) {
dropbear_exit("Bignum error for iqmp\n");
}
buf_putstring(buf, SSH_SIGNKEY_RSA, SSH_SIGNKEY_RSA_LEN);
buf_putmpint(buf, key->n);
buf_putmpint(buf, key->e);
buf_putmpint(buf, key->d);
buf_putmpint(buf, &iqmp);
buf_putmpint(buf, key->p);
buf_putmpint(buf, key->q);
mp_clear(&iqmp);
}
int buf_get_rsa_priv_ossh(buffer *buf, sign_key *akey) {
int ret = DROPBEAR_FAILURE;
dropbear_rsa_key *key = NULL;
mp_int iqmp;
rsa_key_free(akey->rsakey);
akey->rsakey = m_malloc(sizeof(*akey->rsakey));
key = akey->rsakey;
m_mp_alloc_init_multi(&key->e, &key->n, &key->d, &key->p, &key->q, NULL);
buf_eatstring(buf);
m_mp_init(&iqmp);
if (buf_getmpint(buf, key->n) == DROPBEAR_SUCCESS
&& buf_getmpint(buf, key->e) == DROPBEAR_SUCCESS
&& buf_getmpint(buf, key->d) == DROPBEAR_SUCCESS
&& buf_getmpint(buf, &iqmp) == DROPBEAR_SUCCESS
&& buf_getmpint(buf, key->p) == DROPBEAR_SUCCESS
&& buf_getmpint(buf, key->q) == DROPBEAR_SUCCESS) {
ret = DROPBEAR_SUCCESS;
}
mp_clear(&iqmp);
return ret;
}
#endif /* DROPBEAR_RSA */
#if DROPBEAR_ED25519
/* OpenSSH raw private ed25519 format is
string "ssh-ed25519"
uint32 32
byte[32] pubkey
uint32 64
byte[32] privkey
byte[32] pubkey
*/
void buf_put_ed25519_priv_ossh(buffer *buf, const sign_key *akey) {
const dropbear_ed25519_key *key = akey->ed25519key;
dropbear_assert(key != NULL);
buf_putstring(buf, SSH_SIGNKEY_ED25519, SSH_SIGNKEY_ED25519_LEN);
buf_putint(buf, CURVE25519_LEN);
buf_putbytes(buf, key->pub, CURVE25519_LEN);
buf_putint(buf, CURVE25519_LEN*2);
buf_putbytes(buf, key->priv, CURVE25519_LEN);
buf_putbytes(buf, key->pub, CURVE25519_LEN);
}
int buf_get_ed25519_priv_ossh(buffer *buf, sign_key *akey) {
dropbear_ed25519_key *key = NULL;
uint32_t len;
ed25519_key_free(akey->ed25519key);
akey->ed25519key = m_malloc(sizeof(*akey->ed25519key));
key = akey->ed25519key;
/* Parse past the first string and pubkey */
if (buf_get_ed25519_pub_key(buf, key, DROPBEAR_SIGNKEY_ED25519)
== DROPBEAR_FAILURE) {
dropbear_log(LOG_ERR, "Error parsing ed25519 key, pubkey");
return DROPBEAR_FAILURE;
}
len = buf_getint(buf);
if (len != 2*CURVE25519_LEN) {
dropbear_log(LOG_ERR, "Error parsing ed25519 key, bad length");
return DROPBEAR_FAILURE;
}
memcpy(key->priv, buf_getptr(buf, CURVE25519_LEN), CURVE25519_LEN);
buf_incrpos(buf, CURVE25519_LEN);
/* Sanity check */
if (memcmp(buf_getptr(buf, CURVE25519_LEN), key->pub,
CURVE25519_LEN) != 0) {
dropbear_log(LOG_ERR, "Error parsing ed25519 key, mismatch pubkey");
return DROPBEAR_FAILURE;
}
return DROPBEAR_SUCCESS;
}
#endif /* DROPBEAR_ED255219 */