Mercurial > dropbear
comparison rsa.c @ 165:0cfba3034be5
Fixed DEBUG_TRACE macro so that we don't get semicolons left about the place
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sun, 02 Jan 2005 20:25:56 +0000 |
parents | 29a5c7c62350 |
children | c9483550701b |
comparison
equal
deleted
inserted
replaced
161:b9d3f725e00b | 165:0cfba3034be5 |
---|---|
45 * The key will have the same format as buf_put_rsa_key. | 45 * The key will have the same format as buf_put_rsa_key. |
46 * These should be freed with rsa_key_free. | 46 * These should be freed with rsa_key_free. |
47 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ | 47 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ |
48 int buf_get_rsa_pub_key(buffer* buf, rsa_key *key) { | 48 int buf_get_rsa_pub_key(buffer* buf, rsa_key *key) { |
49 | 49 |
50 TRACE(("enter buf_get_rsa_pub_key")); | 50 TRACE(("enter buf_get_rsa_pub_key")) |
51 assert(key != NULL); | 51 assert(key != NULL); |
52 key->e = m_malloc(sizeof(mp_int)); | 52 key->e = m_malloc(sizeof(mp_int)); |
53 key->n = m_malloc(sizeof(mp_int)); | 53 key->n = m_malloc(sizeof(mp_int)); |
54 m_mp_init_multi(key->e, key->n, NULL); | 54 m_mp_init_multi(key->e, key->n, NULL); |
55 key->d = NULL; | 55 key->d = NULL; |
58 | 58 |
59 buf_incrpos(buf, 4+SSH_SIGNKEY_RSA_LEN); /* int + "ssh-rsa" */ | 59 buf_incrpos(buf, 4+SSH_SIGNKEY_RSA_LEN); /* int + "ssh-rsa" */ |
60 | 60 |
61 if (buf_getmpint(buf, key->e) == DROPBEAR_FAILURE | 61 if (buf_getmpint(buf, key->e) == DROPBEAR_FAILURE |
62 || buf_getmpint(buf, key->n) == DROPBEAR_FAILURE) { | 62 || buf_getmpint(buf, key->n) == DROPBEAR_FAILURE) { |
63 TRACE(("leave buf_get_rsa_pub_key: failure")); | 63 TRACE(("leave buf_get_rsa_pub_key: failure")) |
64 return DROPBEAR_FAILURE; | 64 return DROPBEAR_FAILURE; |
65 } | 65 } |
66 | 66 |
67 if (mp_count_bits(key->n) < MIN_RSA_KEYLEN) { | 67 if (mp_count_bits(key->n) < MIN_RSA_KEYLEN) { |
68 dropbear_log(LOG_WARNING, "rsa key too short"); | 68 dropbear_log(LOG_WARNING, "rsa key too short"); |
69 return DROPBEAR_FAILURE; | 69 return DROPBEAR_FAILURE; |
70 } | 70 } |
71 | 71 |
72 TRACE(("leave buf_get_rsa_pub_key: success")); | 72 TRACE(("leave buf_get_rsa_pub_key: success")) |
73 return DROPBEAR_SUCCESS; | 73 return DROPBEAR_SUCCESS; |
74 | 74 |
75 } | 75 } |
76 | 76 |
77 /* Same as buf_get_rsa_pub_key, but reads a private "x" key at the end. | 77 /* Same as buf_get_rsa_pub_key, but reads a private "x" key at the end. |
79 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ | 79 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ |
80 int buf_get_rsa_priv_key(buffer* buf, rsa_key *key) { | 80 int buf_get_rsa_priv_key(buffer* buf, rsa_key *key) { |
81 | 81 |
82 assert(key != NULL); | 82 assert(key != NULL); |
83 | 83 |
84 TRACE(("enter buf_get_rsa_priv_key")); | 84 TRACE(("enter buf_get_rsa_priv_key")) |
85 | 85 |
86 if (buf_get_rsa_pub_key(buf, key) == DROPBEAR_FAILURE) { | 86 if (buf_get_rsa_pub_key(buf, key) == DROPBEAR_FAILURE) { |
87 TRACE(("leave buf_get_rsa_priv_key: pub: ret == DROPBEAR_FAILURE")); | 87 TRACE(("leave buf_get_rsa_priv_key: pub: ret == DROPBEAR_FAILURE")) |
88 return DROPBEAR_FAILURE; | 88 return DROPBEAR_FAILURE; |
89 } | 89 } |
90 | 90 |
91 key->d = m_malloc(sizeof(mp_int)); | 91 key->d = m_malloc(sizeof(mp_int)); |
92 m_mp_init(key->d); | 92 m_mp_init(key->d); |
93 if (buf_getmpint(buf, key->d) == DROPBEAR_FAILURE) { | 93 if (buf_getmpint(buf, key->d) == DROPBEAR_FAILURE) { |
94 TRACE(("leave buf_get_rsa_priv_key: d: ret == DROPBEAR_FAILURE")); | 94 TRACE(("leave buf_get_rsa_priv_key: d: ret == DROPBEAR_FAILURE")) |
95 return DROPBEAR_FAILURE; | 95 return DROPBEAR_FAILURE; |
96 } | 96 } |
97 | 97 |
98 /* old Dropbear private keys didn't keep p and q, so we will ignore them*/ | 98 /* old Dropbear private keys didn't keep p and q, so we will ignore them*/ |
99 if (buf->pos == buf->len) { | 99 if (buf->pos == buf->len) { |
103 key->p = m_malloc(sizeof(mp_int)); | 103 key->p = m_malloc(sizeof(mp_int)); |
104 key->q = m_malloc(sizeof(mp_int)); | 104 key->q = m_malloc(sizeof(mp_int)); |
105 m_mp_init_multi(key->p, key->q, NULL); | 105 m_mp_init_multi(key->p, key->q, NULL); |
106 | 106 |
107 if (buf_getmpint(buf, key->p) == DROPBEAR_FAILURE) { | 107 if (buf_getmpint(buf, key->p) == DROPBEAR_FAILURE) { |
108 TRACE(("leave buf_get_rsa_priv_key: p: ret == DROPBEAR_FAILURE")); | 108 TRACE(("leave buf_get_rsa_priv_key: p: ret == DROPBEAR_FAILURE")) |
109 return DROPBEAR_FAILURE; | 109 return DROPBEAR_FAILURE; |
110 } | 110 } |
111 | 111 |
112 if (buf_getmpint(buf, key->q) == DROPBEAR_FAILURE) { | 112 if (buf_getmpint(buf, key->q) == DROPBEAR_FAILURE) { |
113 TRACE(("leave buf_get_rsa_priv_key: q: ret == DROPBEAR_FAILURE")); | 113 TRACE(("leave buf_get_rsa_priv_key: q: ret == DROPBEAR_FAILURE")) |
114 return DROPBEAR_FAILURE; | 114 return DROPBEAR_FAILURE; |
115 } | 115 } |
116 } | 116 } |
117 | 117 |
118 TRACE(("leave buf_get_rsa_priv_key")); | 118 TRACE(("leave buf_get_rsa_priv_key")) |
119 return DROPBEAR_SUCCESS; | 119 return DROPBEAR_SUCCESS; |
120 } | 120 } |
121 | 121 |
122 | 122 |
123 /* Clear and free the memory used by a public or private key */ | 123 /* Clear and free the memory used by a public or private key */ |
124 void rsa_key_free(rsa_key *key) { | 124 void rsa_key_free(rsa_key *key) { |
125 | 125 |
126 TRACE(("enter rsa_key_free")); | 126 TRACE(("enter rsa_key_free")) |
127 | 127 |
128 if (key == NULL) { | 128 if (key == NULL) { |
129 TRACE(("leave rsa_key_free: key == NULL")); | 129 TRACE(("leave rsa_key_free: key == NULL")) |
130 return; | 130 return; |
131 } | 131 } |
132 if (key->d) { | 132 if (key->d) { |
133 mp_clear(key->d); | 133 mp_clear(key->d); |
134 m_free(key->d); | 134 m_free(key->d); |
148 if (key->q) { | 148 if (key->q) { |
149 mp_clear(key->q); | 149 mp_clear(key->q); |
150 m_free(key->q); | 150 m_free(key->q); |
151 } | 151 } |
152 m_free(key); | 152 m_free(key); |
153 TRACE(("leave rsa_key_free")); | 153 TRACE(("leave rsa_key_free")) |
154 } | 154 } |
155 | 155 |
156 /* Put the public rsa key into the buffer in the required format: | 156 /* Put the public rsa key into the buffer in the required format: |
157 * | 157 * |
158 * string "ssh-rsa" | 158 * string "ssh-rsa" |
159 * mp_int e | 159 * mp_int e |
160 * mp_int n | 160 * mp_int n |
161 */ | 161 */ |
162 void buf_put_rsa_pub_key(buffer* buf, rsa_key *key) { | 162 void buf_put_rsa_pub_key(buffer* buf, rsa_key *key) { |
163 | 163 |
164 TRACE(("enter buf_put_rsa_pub_key")); | 164 TRACE(("enter buf_put_rsa_pub_key")) |
165 assert(key != NULL); | 165 assert(key != NULL); |
166 | 166 |
167 buf_putstring(buf, SSH_SIGNKEY_RSA, SSH_SIGNKEY_RSA_LEN); | 167 buf_putstring(buf, SSH_SIGNKEY_RSA, SSH_SIGNKEY_RSA_LEN); |
168 buf_putmpint(buf, key->e); | 168 buf_putmpint(buf, key->e); |
169 buf_putmpint(buf, key->n); | 169 buf_putmpint(buf, key->n); |
170 | 170 |
171 TRACE(("leave buf_put_rsa_pub_key")); | 171 TRACE(("leave buf_put_rsa_pub_key")) |
172 | 172 |
173 } | 173 } |
174 | 174 |
175 /* Same as buf_put_rsa_pub_key, but with the private "x" key appended */ | 175 /* Same as buf_put_rsa_pub_key, but with the private "x" key appended */ |
176 void buf_put_rsa_priv_key(buffer* buf, rsa_key *key) { | 176 void buf_put_rsa_priv_key(buffer* buf, rsa_key *key) { |
177 | 177 |
178 TRACE(("enter buf_put_rsa_priv_key")); | 178 TRACE(("enter buf_put_rsa_priv_key")) |
179 | 179 |
180 assert(key != NULL); | 180 assert(key != NULL); |
181 buf_put_rsa_pub_key(buf, key); | 181 buf_put_rsa_pub_key(buf, key); |
182 buf_putmpint(buf, key->d); | 182 buf_putmpint(buf, key->d); |
183 | 183 |
188 if (key->q) { | 188 if (key->q) { |
189 buf_putmpint(buf, key->q); | 189 buf_putmpint(buf, key->q); |
190 } | 190 } |
191 | 191 |
192 | 192 |
193 TRACE(("leave buf_put_rsa_priv_key")); | 193 TRACE(("leave buf_put_rsa_priv_key")) |
194 | 194 |
195 } | 195 } |
196 | 196 |
197 #ifdef DROPBEAR_SIGNKEY_VERIFY | 197 #ifdef DROPBEAR_SIGNKEY_VERIFY |
198 /* Verify a signature in buf, made on data by the key given. | 198 /* Verify a signature in buf, made on data by the key given. |
204 DEF_MP_INT(rsa_s); | 204 DEF_MP_INT(rsa_s); |
205 DEF_MP_INT(rsa_mdash); | 205 DEF_MP_INT(rsa_mdash); |
206 mp_int *rsa_em = NULL; | 206 mp_int *rsa_em = NULL; |
207 int ret = DROPBEAR_FAILURE; | 207 int ret = DROPBEAR_FAILURE; |
208 | 208 |
209 TRACE(("enter buf_rsa_verify")); | 209 TRACE(("enter buf_rsa_verify")) |
210 | 210 |
211 assert(key != NULL); | 211 assert(key != NULL); |
212 | 212 |
213 m_mp_init_multi(&rsa_mdash, &rsa_s, NULL); | 213 m_mp_init_multi(&rsa_mdash, &rsa_s, NULL); |
214 | 214 |
215 slen = buf_getint(buf); | 215 slen = buf_getint(buf); |
216 if (slen != (unsigned int)mp_unsigned_bin_size(key->n)) { | 216 if (slen != (unsigned int)mp_unsigned_bin_size(key->n)) { |
217 TRACE(("bad size")); | 217 TRACE(("bad size")) |
218 goto out; | 218 goto out; |
219 } | 219 } |
220 | 220 |
221 if (mp_read_unsigned_bin(&rsa_s, buf_getptr(buf, buf->len - buf->pos), | 221 if (mp_read_unsigned_bin(&rsa_s, buf_getptr(buf, buf->len - buf->pos), |
222 buf->len - buf->pos) != MP_OKAY) { | 222 buf->len - buf->pos) != MP_OKAY) { |
223 TRACE(("failed reading rsa_s")); | 223 TRACE(("failed reading rsa_s")) |
224 goto out; | 224 goto out; |
225 } | 225 } |
226 | 226 |
227 /* check that s <= n-1 */ | 227 /* check that s <= n-1 */ |
228 if (mp_cmp(&rsa_s, key->n) != MP_LT) { | 228 if (mp_cmp(&rsa_s, key->n) != MP_LT) { |
229 TRACE(("s > n-1")); | 229 TRACE(("s > n-1")) |
230 goto out; | 230 goto out; |
231 } | 231 } |
232 | 232 |
233 /* create the magic PKCS padded value */ | 233 /* create the magic PKCS padded value */ |
234 rsa_em = rsa_pad_em(key, data, len); | 234 rsa_em = rsa_pad_em(key, data, len); |
235 | 235 |
236 if (mp_exptmod(&rsa_s, key->e, key->n, &rsa_mdash) != MP_OKAY) { | 236 if (mp_exptmod(&rsa_s, key->e, key->n, &rsa_mdash) != MP_OKAY) { |
237 TRACE(("failed exptmod rsa_s")); | 237 TRACE(("failed exptmod rsa_s")) |
238 goto out; | 238 goto out; |
239 } | 239 } |
240 | 240 |
241 if (mp_cmp(rsa_em, &rsa_mdash) == MP_EQ) { | 241 if (mp_cmp(rsa_em, &rsa_mdash) == MP_EQ) { |
242 /* signature is valid */ | 242 /* signature is valid */ |
243 TRACE(("success!")); | 243 TRACE(("success!")) |
244 ret = DROPBEAR_SUCCESS; | 244 ret = DROPBEAR_SUCCESS; |
245 } | 245 } |
246 | 246 |
247 out: | 247 out: |
248 if (rsa_em) { | 248 if (rsa_em) { |
249 mp_clear(rsa_em); | 249 mp_clear(rsa_em); |
250 m_free(rsa_em); | 250 m_free(rsa_em); |
251 } | 251 } |
252 mp_clear_multi(&rsa_mdash, &rsa_s, NULL); | 252 mp_clear_multi(&rsa_mdash, &rsa_s, NULL); |
253 TRACE(("leave buf_rsa_verify: ret %d", ret)); | 253 TRACE(("leave buf_rsa_verify: ret %d", ret)) |
254 return ret; | 254 return ret; |
255 | 255 |
256 } | 256 } |
257 #endif /* DROPBEAR_SIGNKEY_VERIFY */ | 257 #endif /* DROPBEAR_SIGNKEY_VERIFY */ |
258 | 258 |
264 unsigned int nsize, ssize; | 264 unsigned int nsize, ssize; |
265 unsigned int i; | 265 unsigned int i; |
266 DEF_MP_INT(rsa_s); | 266 DEF_MP_INT(rsa_s); |
267 mp_int *rsa_em = NULL; | 267 mp_int *rsa_em = NULL; |
268 | 268 |
269 TRACE(("enter buf_put_rsa_sign")); | 269 TRACE(("enter buf_put_rsa_sign")) |
270 assert(key != NULL); | 270 assert(key != NULL); |
271 | 271 |
272 rsa_em = rsa_pad_em(key, data, len); | 272 rsa_em = rsa_pad_em(key, data, len); |
273 | 273 |
274 m_mp_init(&rsa_s); | 274 m_mp_init(&rsa_s); |
304 #if defined(DEBUG_RSA) && defined(DEBUG_TRACE) | 304 #if defined(DEBUG_RSA) && defined(DEBUG_TRACE) |
305 printhex(buf->data, buf->len); | 305 printhex(buf->data, buf->len); |
306 #endif | 306 #endif |
307 | 307 |
308 | 308 |
309 TRACE(("leave buf_put_rsa_sign")); | 309 TRACE(("leave buf_put_rsa_sign")) |
310 } | 310 } |
311 | 311 |
312 /* Creates the message value as expected by PKCS, see rfc2437 etc */ | 312 /* Creates the message value as expected by PKCS, see rfc2437 etc */ |
313 /* format to be padded to is: | 313 /* format to be padded to is: |
314 * EM = 01 | FF* | 00 | prefix | hash | 314 * EM = 01 | FF* | 00 | prefix | hash |