Mercurial > dropbear
comparison rsa.c @ 370:9a789fc03f40
Make sure that we clean up key parts if we fail during reading a rsa key
(from Klocwork)
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Thu, 02 Nov 2006 16:10:18 +0000 |
parents | 3cea9d789cca |
children | a124aff0cbf1 |
comparison
equal
deleted
inserted
replaced
369:8eaa6e3ca6eb | 370:9a789fc03f40 |
---|---|
46 * The key will have the same format as buf_put_rsa_key. | 46 * The key will have the same format as buf_put_rsa_key. |
47 * These should be freed with rsa_key_free. | 47 * These should be freed with rsa_key_free. |
48 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ | 48 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ |
49 int buf_get_rsa_pub_key(buffer* buf, rsa_key *key) { | 49 int buf_get_rsa_pub_key(buffer* buf, rsa_key *key) { |
50 | 50 |
51 int ret = DROPBEAR_FAILURE; | |
51 TRACE(("enter buf_get_rsa_pub_key")) | 52 TRACE(("enter buf_get_rsa_pub_key")) |
52 dropbear_assert(key != NULL); | 53 dropbear_assert(key != NULL); |
53 key->e = m_malloc(sizeof(mp_int)); | 54 key->e = m_malloc(sizeof(mp_int)); |
54 key->n = m_malloc(sizeof(mp_int)); | 55 key->n = m_malloc(sizeof(mp_int)); |
55 m_mp_init_multi(key->e, key->n, NULL); | 56 m_mp_init_multi(key->e, key->n, NULL); |
60 buf_incrpos(buf, 4+SSH_SIGNKEY_RSA_LEN); /* int + "ssh-rsa" */ | 61 buf_incrpos(buf, 4+SSH_SIGNKEY_RSA_LEN); /* int + "ssh-rsa" */ |
61 | 62 |
62 if (buf_getmpint(buf, key->e) == DROPBEAR_FAILURE | 63 if (buf_getmpint(buf, key->e) == DROPBEAR_FAILURE |
63 || buf_getmpint(buf, key->n) == DROPBEAR_FAILURE) { | 64 || buf_getmpint(buf, key->n) == DROPBEAR_FAILURE) { |
64 TRACE(("leave buf_get_rsa_pub_key: failure")) | 65 TRACE(("leave buf_get_rsa_pub_key: failure")) |
65 return DROPBEAR_FAILURE; | 66 goto out; |
66 } | 67 } |
67 | 68 |
68 if (mp_count_bits(key->n) < MIN_RSA_KEYLEN) { | 69 if (mp_count_bits(key->n) < MIN_RSA_KEYLEN) { |
69 dropbear_log(LOG_WARNING, "rsa key too short"); | 70 dropbear_log(LOG_WARNING, "rsa key too short"); |
70 return DROPBEAR_FAILURE; | 71 goto out; |
71 } | 72 } |
72 | 73 |
73 TRACE(("leave buf_get_rsa_pub_key: success")) | 74 TRACE(("leave buf_get_rsa_pub_key: success")) |
74 return DROPBEAR_SUCCESS; | 75 ret = DROPBEAR_SUCCESS; |
75 | 76 out: |
76 } | 77 if (ret == DROPBEAR_FAILURE) { |
77 | 78 m_free(key->e); |
78 /* Same as buf_get_rsa_pub_key, but reads a private "x" key at the end. | 79 m_free(key->n); |
80 } | |
81 return ret; | |
82 } | |
83 | |
84 /* Same as buf_get_rsa_pub_key, but reads private bits at the end. | |
79 * Loads a private rsa key from a buffer | 85 * Loads a private rsa key from a buffer |
80 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ | 86 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ |
81 int buf_get_rsa_priv_key(buffer* buf, rsa_key *key) { | 87 int buf_get_rsa_priv_key(buffer* buf, rsa_key *key) { |
82 | 88 int ret = DROPBEAR_FAILURE; |
83 dropbear_assert(key != NULL); | |
84 | 89 |
85 TRACE(("enter buf_get_rsa_priv_key")) | 90 TRACE(("enter buf_get_rsa_priv_key")) |
91 dropbear_assert(key != NULL); | |
86 | 92 |
87 if (buf_get_rsa_pub_key(buf, key) == DROPBEAR_FAILURE) { | 93 if (buf_get_rsa_pub_key(buf, key) == DROPBEAR_FAILURE) { |
88 TRACE(("leave buf_get_rsa_priv_key: pub: ret == DROPBEAR_FAILURE")) | 94 TRACE(("leave buf_get_rsa_priv_key: pub: ret == DROPBEAR_FAILURE")) |
89 return DROPBEAR_FAILURE; | 95 return DROPBEAR_FAILURE; |
90 } | 96 } |
97 | |
98 key->d = NULL; | |
99 key->p = NULL; | |
100 key->q = NULL; | |
91 | 101 |
92 key->d = m_malloc(sizeof(mp_int)); | 102 key->d = m_malloc(sizeof(mp_int)); |
93 m_mp_init(key->d); | 103 m_mp_init(key->d); |
94 if (buf_getmpint(buf, key->d) == DROPBEAR_FAILURE) { | 104 if (buf_getmpint(buf, key->d) == DROPBEAR_FAILURE) { |
95 TRACE(("leave buf_get_rsa_priv_key: d: ret == DROPBEAR_FAILURE")) | 105 TRACE(("leave buf_get_rsa_priv_key: d: ret == DROPBEAR_FAILURE")) |
96 return DROPBEAR_FAILURE; | 106 goto out; |
97 } | 107 } |
98 | 108 |
99 /* old Dropbear private keys didn't keep p and q, so we will ignore them*/ | |
100 if (buf->pos == buf->len) { | 109 if (buf->pos == buf->len) { |
101 key->p = NULL; | 110 /* old Dropbear private keys didn't keep p and q, so we will ignore them*/ |
102 key->q = NULL; | |
103 } else { | 111 } else { |
104 key->p = m_malloc(sizeof(mp_int)); | 112 key->p = m_malloc(sizeof(mp_int)); |
105 key->q = m_malloc(sizeof(mp_int)); | 113 key->q = m_malloc(sizeof(mp_int)); |
106 m_mp_init_multi(key->p, key->q, NULL); | 114 m_mp_init_multi(key->p, key->q, NULL); |
107 | 115 |
108 if (buf_getmpint(buf, key->p) == DROPBEAR_FAILURE) { | 116 if (buf_getmpint(buf, key->p) == DROPBEAR_FAILURE) { |
109 TRACE(("leave buf_get_rsa_priv_key: p: ret == DROPBEAR_FAILURE")) | 117 TRACE(("leave buf_get_rsa_priv_key: p: ret == DROPBEAR_FAILURE")) |
110 return DROPBEAR_FAILURE; | 118 goto out; |
111 } | 119 } |
112 | 120 |
113 if (buf_getmpint(buf, key->q) == DROPBEAR_FAILURE) { | 121 if (buf_getmpint(buf, key->q) == DROPBEAR_FAILURE) { |
114 TRACE(("leave buf_get_rsa_priv_key: q: ret == DROPBEAR_FAILURE")) | 122 TRACE(("leave buf_get_rsa_priv_key: q: ret == DROPBEAR_FAILURE")) |
115 return DROPBEAR_FAILURE; | 123 goto out; |
116 } | 124 } |
117 } | 125 } |
118 | 126 |
127 ret = DROPBEAR_SUCCESS; | |
128 out: | |
129 if (ret == DROPBEAR_FAILURE) { | |
130 m_free(key->d); | |
131 m_free(key->p); | |
132 m_free(key->q); | |
133 } | |
119 TRACE(("leave buf_get_rsa_priv_key")) | 134 TRACE(("leave buf_get_rsa_priv_key")) |
120 return DROPBEAR_SUCCESS; | 135 return ret; |
121 } | 136 } |
122 | 137 |
123 | 138 |
124 /* Clear and free the memory used by a public or private key */ | 139 /* Clear and free the memory used by a public or private key */ |
125 void rsa_key_free(rsa_key *key) { | 140 void rsa_key_free(rsa_key *key) { |