comparison signkey_ossh.c @ 1908:eadd023fde4d

Support RSA OpenSSH new format in dropbearconvert Added support for reading and writing. PEM writing support has been removed. OpenSSH file format routines have been moved to signkey_ossh.c
author Matt Johnston <matt@ucc.asn.au>
date Tue, 29 Mar 2022 22:27:55 +0800
parents
children ced53051e200
comparison
equal deleted inserted replaced
1907:3e0aacf0a4f3 1908:eadd023fde4d
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
13 #if DROPBEAR_RSA
14 /* OpenSSH raw private RSA format is
15 string "ssh-rsa"
16 mpint n
17 mpint e
18 mpint d
19 mpint iqmp (q^-1) mod p
20 mpint p
21 mpint q
22 */
23
24 void buf_put_rsa_priv_ossh(buffer *buf, const sign_key *akey) {
25 const dropbear_rsa_key *key = akey->rsakey;
26 mp_int iqmp;
27
28 dropbear_assert(key != NULL);
29 if (!(key->p && key->q)) {
30 dropbear_exit("Pre-0.33 Dropbear keys cannot be converted to OpenSSH keys.\n");
31 }
32
33 m_mp_init(&iqmp);
34 /* iqmp = (q^-1) mod p */
35 if (mp_invmod(key->q, key->p, &iqmp) != MP_OKAY) {
36 dropbear_exit("Bignum error for iqmp\n");
37 }
38 buf_putstring(buf, SSH_SIGNKEY_RSA, SSH_SIGNKEY_RSA_LEN);
39 buf_putmpint(buf, key->n);
40 buf_putmpint(buf, key->e);
41 buf_putmpint(buf, key->d);
42 buf_putmpint(buf, &iqmp);
43 buf_putmpint(buf, key->p);
44 buf_putmpint(buf, key->q);
45 mp_clear(&iqmp);
46 }
47
48 int buf_get_rsa_priv_ossh(buffer *buf, sign_key *akey) {
49 int ret = DROPBEAR_FAILURE;
50 dropbear_rsa_key *key = NULL;
51 mp_int iqmp;
52
53 rsa_key_free(akey->rsakey);
54 akey->rsakey = m_malloc(sizeof(*akey->rsakey));
55 key = akey->rsakey;
56 m_mp_alloc_init_multi(&key->e, &key->n, &key->d, &key->p, &key->q, NULL);
57
58 buf_eatstring(buf);
59 m_mp_init(&iqmp);
60 if (buf_getmpint(buf, key->n) == DROPBEAR_SUCCESS
61 && buf_getmpint(buf, key->e) == DROPBEAR_SUCCESS
62 && buf_getmpint(buf, key->d) == DROPBEAR_SUCCESS
63 && buf_getmpint(buf, &iqmp) == DROPBEAR_SUCCESS
64 && buf_getmpint(buf, key->p) == DROPBEAR_SUCCESS
65 && buf_getmpint(buf, key->q) == DROPBEAR_SUCCESS) {
66 ret = DROPBEAR_SUCCESS;
67 }
68 mp_clear(&iqmp);
69 return ret;
70 }
71
72 #endif /* DROPBEAR_RSA */
73
74 #if DROPBEAR_ED25519
75 /* OpenSSH raw private ed25519 format is
76 string "ssh-ed25519"
77 uint32 32
78 byte[32] pubkey
79 uint32 64
80 byte[32] privkey
81 byte[32] pubkey
82 */
83
84 void buf_put_ed25519_priv_ossh(buffer *buf, const sign_key *akey) {
85 const dropbear_ed25519_key *key = akey->ed25519key;
86 dropbear_assert(key != NULL);
87 buf_putstring(buf, SSH_SIGNKEY_ED25519, SSH_SIGNKEY_ED25519_LEN);
88 buf_putint(buf, CURVE25519_LEN);
89 buf_putbytes(buf, key->pub, CURVE25519_LEN);
90 buf_putint(buf, CURVE25519_LEN*2);
91 buf_putbytes(buf, key->priv, CURVE25519_LEN);
92 buf_putbytes(buf, key->pub, CURVE25519_LEN);
93 }
94
95 int buf_get_ed25519_priv_ossh(buffer *buf, sign_key *akey) {
96 dropbear_ed25519_key *key = NULL;
97 uint32_t len;
98
99 ed25519_key_free(akey->ed25519key);
100 akey->ed25519key = m_malloc(sizeof(*akey->ed25519key));
101 key = akey->ed25519key;
102
103 /* Parse past the first string and pubkey */
104 if (buf_get_ed25519_pub_key(buf, key, DROPBEAR_SIGNKEY_ED25519)
105 == DROPBEAR_FAILURE) {
106 dropbear_log(LOG_ERR, "Error parsing ed25519 key, pubkey");
107 return DROPBEAR_FAILURE;
108 }
109 len = buf_getint(buf);
110 if (len != 2*CURVE25519_LEN) {
111 dropbear_log(LOG_ERR, "Error parsing ed25519 key, bad length");
112 return DROPBEAR_FAILURE;
113 }
114 memcpy(key->priv, buf_getptr(buf, CURVE25519_LEN), CURVE25519_LEN);
115 buf_incrpos(buf, CURVE25519_LEN);
116
117 /* Sanity check */
118 if (memcmp(buf_getptr(buf, CURVE25519_LEN), key->pub,
119 CURVE25519_LEN) != 0) {
120 dropbear_log(LOG_ERR, "Error parsing ed25519 key, mismatch pubkey");
121 return DROPBEAR_FAILURE;
122 }
123 return DROPBEAR_SUCCESS;
124 }
125 #endif /* DROPBEAR_ED255219 */