diff options
Diffstat (limited to 'key.c')
-rw-r--r-- | key.c | 2751 |
1 files changed, 302 insertions, 2449 deletions
@@ -1,2090 +1,242 @@ | |||
1 | /* $OpenBSD: key.c,v 1.116 2014/02/02 03:44:31 djm Exp $ */ | 1 | /* $OpenBSD: key.c,v 1.122 2014/07/22 01:18:50 dtucker Exp $ */ |
2 | /* | 2 | /* |
3 | * read_bignum(): | 3 | * placed in the public domain |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | ||
5 | * | ||
6 | * As far as I am concerned, the code I have written for this software | ||
7 | * can be used freely for any purpose. Any derived versions of this | ||
8 | * software must be clearly marked as such, and if the derived work is | ||
9 | * incompatible with the protocol description in the RFC file, it must be | ||
10 | * called by a name other than "ssh" or "Secure Shell". | ||
11 | * | ||
12 | * | ||
13 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. | ||
14 | * Copyright (c) 2008 Alexander von Gernler. All rights reserved. | ||
15 | * | ||
16 | * Redistribution and use in source and binary forms, with or without | ||
17 | * modification, are permitted provided that the following conditions | ||
18 | * are met: | ||
19 | * 1. Redistributions of source code must retain the above copyright | ||
20 | * notice, this list of conditions and the following disclaimer. | ||
21 | * 2. Redistributions in binary form must reproduce the above copyright | ||
22 | * notice, this list of conditions and the following disclaimer in the | ||
23 | * documentation and/or other materials provided with the distribution. | ||
24 | * | ||
25 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | ||
26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
27 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
28 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
29 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
30 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
31 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
32 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
33 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
35 | */ | 4 | */ |
36 | 5 | ||
37 | #include "includes.h" | 6 | #include "includes.h" |
38 | 7 | ||
39 | #include <sys/param.h> | 8 | #include <sys/param.h> |
40 | #include <sys/types.h> | 9 | #include <sys/types.h> |
41 | 10 | #include <errno.h> | |
42 | #include "crypto_api.h" | ||
43 | |||
44 | #include <openssl/evp.h> | ||
45 | #include <openbsd-compat/openssl-compat.h> | ||
46 | |||
47 | #include <stdarg.h> | 11 | #include <stdarg.h> |
48 | #include <stdio.h> | 12 | #include <stdio.h> |
49 | #include <string.h> | ||
50 | 13 | ||
51 | #include "xmalloc.h" | 14 | #define SSH_KEY_NO_DEFINE |
52 | #include "key.h" | 15 | #include "key.h" |
53 | #include "rsa.h" | ||
54 | #include "uuencode.h" | ||
55 | #include "buffer.h" | ||
56 | #include "log.h" | ||
57 | #include "misc.h" | ||
58 | #include "ssh2.h" | ||
59 | #include "digest.h" | ||
60 | |||
61 | static int to_blob(const Key *, u_char **, u_int *, int); | ||
62 | static Key *key_from_blob2(const u_char *, u_int, int); | ||
63 | |||
64 | static struct KeyCert * | ||
65 | cert_new(void) | ||
66 | { | ||
67 | struct KeyCert *cert; | ||
68 | |||
69 | cert = xcalloc(1, sizeof(*cert)); | ||
70 | buffer_init(&cert->certblob); | ||
71 | buffer_init(&cert->critical); | ||
72 | buffer_init(&cert->extensions); | ||
73 | cert->key_id = NULL; | ||
74 | cert->principals = NULL; | ||
75 | cert->signature_key = NULL; | ||
76 | return cert; | ||
77 | } | ||
78 | |||
79 | Key * | ||
80 | key_new(int type) | ||
81 | { | ||
82 | Key *k; | ||
83 | RSA *rsa; | ||
84 | DSA *dsa; | ||
85 | k = xcalloc(1, sizeof(*k)); | ||
86 | k->type = type; | ||
87 | k->ecdsa = NULL; | ||
88 | k->ecdsa_nid = -1; | ||
89 | k->dsa = NULL; | ||
90 | k->rsa = NULL; | ||
91 | k->cert = NULL; | ||
92 | k->ed25519_sk = NULL; | ||
93 | k->ed25519_pk = NULL; | ||
94 | switch (k->type) { | ||
95 | case KEY_RSA1: | ||
96 | case KEY_RSA: | ||
97 | case KEY_RSA_CERT_V00: | ||
98 | case KEY_RSA_CERT: | ||
99 | if ((rsa = RSA_new()) == NULL) | ||
100 | fatal("key_new: RSA_new failed"); | ||
101 | if ((rsa->n = BN_new()) == NULL) | ||
102 | fatal("key_new: BN_new failed"); | ||
103 | if ((rsa->e = BN_new()) == NULL) | ||
104 | fatal("key_new: BN_new failed"); | ||
105 | k->rsa = rsa; | ||
106 | break; | ||
107 | case KEY_DSA: | ||
108 | case KEY_DSA_CERT_V00: | ||
109 | case KEY_DSA_CERT: | ||
110 | if ((dsa = DSA_new()) == NULL) | ||
111 | fatal("key_new: DSA_new failed"); | ||
112 | if ((dsa->p = BN_new()) == NULL) | ||
113 | fatal("key_new: BN_new failed"); | ||
114 | if ((dsa->q = BN_new()) == NULL) | ||
115 | fatal("key_new: BN_new failed"); | ||
116 | if ((dsa->g = BN_new()) == NULL) | ||
117 | fatal("key_new: BN_new failed"); | ||
118 | if ((dsa->pub_key = BN_new()) == NULL) | ||
119 | fatal("key_new: BN_new failed"); | ||
120 | k->dsa = dsa; | ||
121 | break; | ||
122 | #ifdef OPENSSL_HAS_ECC | ||
123 | case KEY_ECDSA: | ||
124 | case KEY_ECDSA_CERT: | ||
125 | /* Cannot do anything until we know the group */ | ||
126 | break; | ||
127 | #endif | ||
128 | case KEY_ED25519: | ||
129 | case KEY_ED25519_CERT: | ||
130 | /* no need to prealloc */ | ||
131 | break; | ||
132 | case KEY_UNSPEC: | ||
133 | break; | ||
134 | default: | ||
135 | fatal("key_new: bad key type %d", k->type); | ||
136 | break; | ||
137 | } | ||
138 | 16 | ||
139 | if (key_is_cert(k)) | 17 | #include "compat.h" |
140 | k->cert = cert_new(); | 18 | #include "sshkey.h" |
141 | 19 | #include "ssherr.h" | |
142 | return k; | 20 | #include "log.h" |
143 | } | 21 | #include "authfile.h" |
144 | 22 | ||
145 | void | 23 | void |
146 | key_add_private(Key *k) | 24 | key_add_private(Key *k) |
147 | { | 25 | { |
148 | switch (k->type) { | 26 | int r; |
149 | case KEY_RSA1: | 27 | |
150 | case KEY_RSA: | 28 | if ((r = sshkey_add_private(k)) != 0) |
151 | case KEY_RSA_CERT_V00: | 29 | fatal("%s: %s", __func__, ssh_err(r)); |
152 | case KEY_RSA_CERT: | ||
153 | if ((k->rsa->d = BN_new()) == NULL) | ||
154 | fatal("key_new_private: BN_new failed"); | ||
155 | if ((k->rsa->iqmp = BN_new()) == NULL) | ||
156 | fatal("key_new_private: BN_new failed"); | ||
157 | if ((k->rsa->q = BN_new()) == NULL) | ||
158 | fatal("key_new_private: BN_new failed"); | ||
159 | if ((k->rsa->p = BN_new()) == NULL) | ||
160 | fatal("key_new_private: BN_new failed"); | ||
161 | if ((k->rsa->dmq1 = BN_new()) == NULL) | ||
162 | fatal("key_new_private: BN_new failed"); | ||
163 | if ((k->rsa->dmp1 = BN_new()) == NULL) | ||
164 | fatal("key_new_private: BN_new failed"); | ||
165 | break; | ||
166 | case KEY_DSA: | ||
167 | case KEY_DSA_CERT_V00: | ||
168 | case KEY_DSA_CERT: | ||
169 | if ((k->dsa->priv_key = BN_new()) == NULL) | ||
170 | fatal("key_new_private: BN_new failed"); | ||
171 | break; | ||
172 | case KEY_ECDSA: | ||
173 | case KEY_ECDSA_CERT: | ||
174 | /* Cannot do anything until we know the group */ | ||
175 | break; | ||
176 | case KEY_ED25519: | ||
177 | case KEY_ED25519_CERT: | ||
178 | /* no need to prealloc */ | ||
179 | break; | ||
180 | case KEY_UNSPEC: | ||
181 | break; | ||
182 | default: | ||
183 | break; | ||
184 | } | ||
185 | } | 30 | } |
186 | 31 | ||
187 | Key * | 32 | Key * |
188 | key_new_private(int type) | 33 | key_new_private(int type) |
189 | { | 34 | { |
190 | Key *k = key_new(type); | 35 | Key *ret = NULL; |
191 | |||
192 | key_add_private(k); | ||
193 | return k; | ||
194 | } | ||
195 | |||
196 | static void | ||
197 | cert_free(struct KeyCert *cert) | ||
198 | { | ||
199 | u_int i; | ||
200 | |||
201 | buffer_free(&cert->certblob); | ||
202 | buffer_free(&cert->critical); | ||
203 | buffer_free(&cert->extensions); | ||
204 | free(cert->key_id); | ||
205 | for (i = 0; i < cert->nprincipals; i++) | ||
206 | free(cert->principals[i]); | ||
207 | free(cert->principals); | ||
208 | if (cert->signature_key != NULL) | ||
209 | key_free(cert->signature_key); | ||
210 | free(cert); | ||
211 | } | ||
212 | |||
213 | void | ||
214 | key_free(Key *k) | ||
215 | { | ||
216 | if (k == NULL) | ||
217 | fatal("key_free: key is NULL"); | ||
218 | switch (k->type) { | ||
219 | case KEY_RSA1: | ||
220 | case KEY_RSA: | ||
221 | case KEY_RSA_CERT_V00: | ||
222 | case KEY_RSA_CERT: | ||
223 | if (k->rsa != NULL) | ||
224 | RSA_free(k->rsa); | ||
225 | k->rsa = NULL; | ||
226 | break; | ||
227 | case KEY_DSA: | ||
228 | case KEY_DSA_CERT_V00: | ||
229 | case KEY_DSA_CERT: | ||
230 | if (k->dsa != NULL) | ||
231 | DSA_free(k->dsa); | ||
232 | k->dsa = NULL; | ||
233 | break; | ||
234 | #ifdef OPENSSL_HAS_ECC | ||
235 | case KEY_ECDSA: | ||
236 | case KEY_ECDSA_CERT: | ||
237 | if (k->ecdsa != NULL) | ||
238 | EC_KEY_free(k->ecdsa); | ||
239 | k->ecdsa = NULL; | ||
240 | break; | ||
241 | #endif | ||
242 | case KEY_ED25519: | ||
243 | case KEY_ED25519_CERT: | ||
244 | if (k->ed25519_pk) { | ||
245 | explicit_bzero(k->ed25519_pk, ED25519_PK_SZ); | ||
246 | free(k->ed25519_pk); | ||
247 | k->ed25519_pk = NULL; | ||
248 | } | ||
249 | if (k->ed25519_sk) { | ||
250 | explicit_bzero(k->ed25519_sk, ED25519_SK_SZ); | ||
251 | free(k->ed25519_sk); | ||
252 | k->ed25519_sk = NULL; | ||
253 | } | ||
254 | break; | ||
255 | case KEY_UNSPEC: | ||
256 | break; | ||
257 | default: | ||
258 | fatal("key_free: bad key type %d", k->type); | ||
259 | break; | ||
260 | } | ||
261 | if (key_is_cert(k)) { | ||
262 | if (k->cert != NULL) | ||
263 | cert_free(k->cert); | ||
264 | k->cert = NULL; | ||
265 | } | ||
266 | |||
267 | free(k); | ||
268 | } | ||
269 | |||
270 | static int | ||
271 | cert_compare(struct KeyCert *a, struct KeyCert *b) | ||
272 | { | ||
273 | if (a == NULL && b == NULL) | ||
274 | return 1; | ||
275 | if (a == NULL || b == NULL) | ||
276 | return 0; | ||
277 | if (buffer_len(&a->certblob) != buffer_len(&b->certblob)) | ||
278 | return 0; | ||
279 | if (timingsafe_bcmp(buffer_ptr(&a->certblob), buffer_ptr(&b->certblob), | ||
280 | buffer_len(&a->certblob)) != 0) | ||
281 | return 0; | ||
282 | return 1; | ||
283 | } | ||
284 | |||
285 | /* | ||
286 | * Compare public portions of key only, allowing comparisons between | ||
287 | * certificates and plain keys too. | ||
288 | */ | ||
289 | int | ||
290 | key_equal_public(const Key *a, const Key *b) | ||
291 | { | ||
292 | #ifdef OPENSSL_HAS_ECC | ||
293 | BN_CTX *bnctx; | ||
294 | #endif | ||
295 | 36 | ||
296 | if (a == NULL || b == NULL || | 37 | if ((ret = sshkey_new_private(type)) == NULL) |
297 | key_type_plain(a->type) != key_type_plain(b->type)) | 38 | fatal("%s: failed", __func__); |
298 | return 0; | 39 | return ret; |
299 | |||
300 | switch (a->type) { | ||
301 | case KEY_RSA1: | ||
302 | case KEY_RSA_CERT_V00: | ||
303 | case KEY_RSA_CERT: | ||
304 | case KEY_RSA: | ||
305 | return a->rsa != NULL && b->rsa != NULL && | ||
306 | BN_cmp(a->rsa->e, b->rsa->e) == 0 && | ||
307 | BN_cmp(a->rsa->n, b->rsa->n) == 0; | ||
308 | case KEY_DSA_CERT_V00: | ||
309 | case KEY_DSA_CERT: | ||
310 | case KEY_DSA: | ||
311 | return a->dsa != NULL && b->dsa != NULL && | ||
312 | BN_cmp(a->dsa->p, b->dsa->p) == 0 && | ||
313 | BN_cmp(a->dsa->q, b->dsa->q) == 0 && | ||
314 | BN_cmp(a->dsa->g, b->dsa->g) == 0 && | ||
315 | BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0; | ||
316 | #ifdef OPENSSL_HAS_ECC | ||
317 | case KEY_ECDSA_CERT: | ||
318 | case KEY_ECDSA: | ||
319 | if (a->ecdsa == NULL || b->ecdsa == NULL || | ||
320 | EC_KEY_get0_public_key(a->ecdsa) == NULL || | ||
321 | EC_KEY_get0_public_key(b->ecdsa) == NULL) | ||
322 | return 0; | ||
323 | if ((bnctx = BN_CTX_new()) == NULL) | ||
324 | fatal("%s: BN_CTX_new failed", __func__); | ||
325 | if (EC_GROUP_cmp(EC_KEY_get0_group(a->ecdsa), | ||
326 | EC_KEY_get0_group(b->ecdsa), bnctx) != 0 || | ||
327 | EC_POINT_cmp(EC_KEY_get0_group(a->ecdsa), | ||
328 | EC_KEY_get0_public_key(a->ecdsa), | ||
329 | EC_KEY_get0_public_key(b->ecdsa), bnctx) != 0) { | ||
330 | BN_CTX_free(bnctx); | ||
331 | return 0; | ||
332 | } | ||
333 | BN_CTX_free(bnctx); | ||
334 | return 1; | ||
335 | #endif /* OPENSSL_HAS_ECC */ | ||
336 | case KEY_ED25519: | ||
337 | case KEY_ED25519_CERT: | ||
338 | return a->ed25519_pk != NULL && b->ed25519_pk != NULL && | ||
339 | memcmp(a->ed25519_pk, b->ed25519_pk, ED25519_PK_SZ) == 0; | ||
340 | default: | ||
341 | fatal("key_equal: bad key type %d", a->type); | ||
342 | } | ||
343 | /* NOTREACHED */ | ||
344 | } | ||
345 | |||
346 | int | ||
347 | key_equal(const Key *a, const Key *b) | ||
348 | { | ||
349 | if (a == NULL || b == NULL || a->type != b->type) | ||
350 | return 0; | ||
351 | if (key_is_cert(a)) { | ||
352 | if (!cert_compare(a->cert, b->cert)) | ||
353 | return 0; | ||
354 | } | ||
355 | return key_equal_public(a, b); | ||
356 | } | 40 | } |
357 | 41 | ||
358 | u_char* | 42 | u_char* |
359 | key_fingerprint_raw(const Key *k, enum fp_type dgst_type, | 43 | key_fingerprint_raw(const Key *k, enum fp_type dgst_type, |
360 | u_int *dgst_raw_length) | 44 | u_int *dgst_raw_length) |
361 | { | 45 | { |
362 | u_char *blob = NULL; | 46 | u_char *ret = NULL; |
363 | u_char *retval = NULL; | 47 | size_t dlen; |
364 | u_int len = 0; | 48 | int r; |
365 | int nlen, elen, hash_alg = -1; | 49 | |
366 | 50 | if (dgst_raw_length != NULL) | |
367 | *dgst_raw_length = 0; | 51 | *dgst_raw_length = 0; |
368 | 52 | if ((r = sshkey_fingerprint_raw(k, dgst_type, &ret, &dlen)) != 0) | |
369 | /* XXX switch to DIGEST_* directly? */ | 53 | fatal("%s: %s", __func__, ssh_err(r)); |
370 | switch (dgst_type) { | 54 | if (dlen > INT_MAX) |
371 | case SSH_FP_MD5: | 55 | fatal("%s: giant len %zu", __func__, dlen); |
372 | hash_alg = SSH_DIGEST_MD5; | 56 | *dgst_raw_length = dlen; |
373 | break; | 57 | return ret; |
374 | case SSH_FP_SHA1: | ||
375 | hash_alg = SSH_DIGEST_SHA1; | ||
376 | break; | ||
377 | case SSH_FP_SHA256: | ||
378 | hash_alg = SSH_DIGEST_SHA256; | ||
379 | break; | ||
380 | default: | ||
381 | fatal("%s: bad digest type %d", __func__, dgst_type); | ||
382 | } | ||
383 | switch (k->type) { | ||
384 | case KEY_RSA1: | ||
385 | nlen = BN_num_bytes(k->rsa->n); | ||
386 | elen = BN_num_bytes(k->rsa->e); | ||
387 | len = nlen + elen; | ||
388 | blob = xmalloc(len); | ||
389 | BN_bn2bin(k->rsa->n, blob); | ||
390 | BN_bn2bin(k->rsa->e, blob + nlen); | ||
391 | break; | ||
392 | case KEY_DSA: | ||
393 | case KEY_ECDSA: | ||
394 | case KEY_RSA: | ||
395 | case KEY_ED25519: | ||
396 | key_to_blob(k, &blob, &len); | ||
397 | break; | ||
398 | case KEY_DSA_CERT_V00: | ||
399 | case KEY_RSA_CERT_V00: | ||
400 | case KEY_DSA_CERT: | ||
401 | case KEY_ECDSA_CERT: | ||
402 | case KEY_RSA_CERT: | ||
403 | case KEY_ED25519_CERT: | ||
404 | /* We want a fingerprint of the _key_ not of the cert */ | ||
405 | to_blob(k, &blob, &len, 1); | ||
406 | break; | ||
407 | case KEY_UNSPEC: | ||
408 | return retval; | ||
409 | default: | ||
410 | fatal("%s: bad key type %d", __func__, k->type); | ||
411 | break; | ||
412 | } | ||
413 | if (blob != NULL) { | ||
414 | retval = xmalloc(SSH_DIGEST_MAX_LENGTH); | ||
415 | if ((ssh_digest_memory(hash_alg, blob, len, | ||
416 | retval, SSH_DIGEST_MAX_LENGTH)) != 0) | ||
417 | fatal("%s: digest_memory failed", __func__); | ||
418 | explicit_bzero(blob, len); | ||
419 | free(blob); | ||
420 | *dgst_raw_length = ssh_digest_bytes(hash_alg); | ||
421 | } else { | ||
422 | fatal("%s: blob is null", __func__); | ||
423 | } | ||
424 | return retval; | ||
425 | } | ||
426 | |||
427 | static char * | ||
428 | key_fingerprint_hex(u_char *dgst_raw, u_int dgst_raw_len) | ||
429 | { | ||
430 | char *retval; | ||
431 | u_int i; | ||
432 | |||
433 | retval = xcalloc(1, dgst_raw_len * 3 + 1); | ||
434 | for (i = 0; i < dgst_raw_len; i++) { | ||
435 | char hex[4]; | ||
436 | snprintf(hex, sizeof(hex), "%02x:", dgst_raw[i]); | ||
437 | strlcat(retval, hex, dgst_raw_len * 3 + 1); | ||
438 | } | ||
439 | |||
440 | /* Remove the trailing ':' character */ | ||
441 | retval[(dgst_raw_len * 3) - 1] = '\0'; | ||
442 | return retval; | ||
443 | } | ||
444 | |||
445 | static char * | ||
446 | key_fingerprint_bubblebabble(u_char *dgst_raw, u_int dgst_raw_len) | ||
447 | { | ||
448 | char vowels[] = { 'a', 'e', 'i', 'o', 'u', 'y' }; | ||
449 | char consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm', | ||
450 | 'n', 'p', 'r', 's', 't', 'v', 'z', 'x' }; | ||
451 | u_int i, j = 0, rounds, seed = 1; | ||
452 | char *retval; | ||
453 | |||
454 | rounds = (dgst_raw_len / 2) + 1; | ||
455 | retval = xcalloc((rounds * 6), sizeof(char)); | ||
456 | retval[j++] = 'x'; | ||
457 | for (i = 0; i < rounds; i++) { | ||
458 | u_int idx0, idx1, idx2, idx3, idx4; | ||
459 | if ((i + 1 < rounds) || (dgst_raw_len % 2 != 0)) { | ||
460 | idx0 = (((((u_int)(dgst_raw[2 * i])) >> 6) & 3) + | ||
461 | seed) % 6; | ||
462 | idx1 = (((u_int)(dgst_raw[2 * i])) >> 2) & 15; | ||
463 | idx2 = ((((u_int)(dgst_raw[2 * i])) & 3) + | ||
464 | (seed / 6)) % 6; | ||
465 | retval[j++] = vowels[idx0]; | ||
466 | retval[j++] = consonants[idx1]; | ||
467 | retval[j++] = vowels[idx2]; | ||
468 | if ((i + 1) < rounds) { | ||
469 | idx3 = (((u_int)(dgst_raw[(2 * i) + 1])) >> 4) & 15; | ||
470 | idx4 = (((u_int)(dgst_raw[(2 * i) + 1]))) & 15; | ||
471 | retval[j++] = consonants[idx3]; | ||
472 | retval[j++] = '-'; | ||
473 | retval[j++] = consonants[idx4]; | ||
474 | seed = ((seed * 5) + | ||
475 | ((((u_int)(dgst_raw[2 * i])) * 7) + | ||
476 | ((u_int)(dgst_raw[(2 * i) + 1])))) % 36; | ||
477 | } | ||
478 | } else { | ||
479 | idx0 = seed % 6; | ||
480 | idx1 = 16; | ||
481 | idx2 = seed / 6; | ||
482 | retval[j++] = vowels[idx0]; | ||
483 | retval[j++] = consonants[idx1]; | ||
484 | retval[j++] = vowels[idx2]; | ||
485 | } | ||
486 | } | ||
487 | retval[j++] = 'x'; | ||
488 | retval[j++] = '\0'; | ||
489 | return retval; | ||
490 | } | ||
491 | |||
492 | /* | ||
493 | * Draw an ASCII-Art representing the fingerprint so human brain can | ||
494 | * profit from its built-in pattern recognition ability. | ||
495 | * This technique is called "random art" and can be found in some | ||
496 | * scientific publications like this original paper: | ||
497 | * | ||
498 | * "Hash Visualization: a New Technique to improve Real-World Security", | ||
499 | * Perrig A. and Song D., 1999, International Workshop on Cryptographic | ||
500 | * Techniques and E-Commerce (CrypTEC '99) | ||
501 | * sparrow.ece.cmu.edu/~adrian/projects/validation/validation.pdf | ||
502 | * | ||
503 | * The subject came up in a talk by Dan Kaminsky, too. | ||
504 | * | ||
505 | * If you see the picture is different, the key is different. | ||
506 | * If the picture looks the same, you still know nothing. | ||
507 | * | ||
508 | * The algorithm used here is a worm crawling over a discrete plane, | ||
509 | * leaving a trace (augmenting the field) everywhere it goes. | ||
510 | * Movement is taken from dgst_raw 2bit-wise. Bumping into walls | ||
511 | * makes the respective movement vector be ignored for this turn. | ||
512 | * Graphs are not unambiguous, because circles in graphs can be | ||
513 | * walked in either direction. | ||
514 | */ | ||
515 | |||
516 | /* | ||
517 | * Field sizes for the random art. Have to be odd, so the starting point | ||
518 | * can be in the exact middle of the picture, and FLDBASE should be >=8 . | ||
519 | * Else pictures would be too dense, and drawing the frame would | ||
520 | * fail, too, because the key type would not fit in anymore. | ||
521 | */ | ||
522 | #define FLDBASE 8 | ||
523 | #define FLDSIZE_Y (FLDBASE + 1) | ||
524 | #define FLDSIZE_X (FLDBASE * 2 + 1) | ||
525 | static char * | ||
526 | key_fingerprint_randomart(u_char *dgst_raw, u_int dgst_raw_len, const Key *k) | ||
527 | { | ||
528 | /* | ||
529 | * Chars to be used after each other every time the worm | ||
530 | * intersects with itself. Matter of taste. | ||
531 | */ | ||
532 | char *augmentation_string = " .o+=*BOX@%&#/^SE"; | ||
533 | char *retval, *p; | ||
534 | u_char field[FLDSIZE_X][FLDSIZE_Y]; | ||
535 | u_int i, b; | ||
536 | int x, y; | ||
537 | size_t len = strlen(augmentation_string) - 1; | ||
538 | |||
539 | retval = xcalloc(1, (FLDSIZE_X + 3) * (FLDSIZE_Y + 2)); | ||
540 | |||
541 | /* initialize field */ | ||
542 | memset(field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof(char)); | ||
543 | x = FLDSIZE_X / 2; | ||
544 | y = FLDSIZE_Y / 2; | ||
545 | |||
546 | /* process raw key */ | ||
547 | for (i = 0; i < dgst_raw_len; i++) { | ||
548 | int input; | ||
549 | /* each byte conveys four 2-bit move commands */ | ||
550 | input = dgst_raw[i]; | ||
551 | for (b = 0; b < 4; b++) { | ||
552 | /* evaluate 2 bit, rest is shifted later */ | ||
553 | x += (input & 0x1) ? 1 : -1; | ||
554 | y += (input & 0x2) ? 1 : -1; | ||
555 | |||
556 | /* assure we are still in bounds */ | ||
557 | x = MAX(x, 0); | ||
558 | y = MAX(y, 0); | ||
559 | x = MIN(x, FLDSIZE_X - 1); | ||
560 | y = MIN(y, FLDSIZE_Y - 1); | ||
561 | |||
562 | /* augment the field */ | ||
563 | if (field[x][y] < len - 2) | ||
564 | field[x][y]++; | ||
565 | input = input >> 2; | ||
566 | } | ||
567 | } | ||
568 | |||
569 | /* mark starting point and end point*/ | ||
570 | field[FLDSIZE_X / 2][FLDSIZE_Y / 2] = len - 1; | ||
571 | field[x][y] = len; | ||
572 | |||
573 | /* fill in retval */ | ||
574 | snprintf(retval, FLDSIZE_X, "+--[%4s %4u]", key_type(k), key_size(k)); | ||
575 | p = strchr(retval, '\0'); | ||
576 | |||
577 | /* output upper border */ | ||
578 | for (i = p - retval - 1; i < FLDSIZE_X; i++) | ||
579 | *p++ = '-'; | ||
580 | *p++ = '+'; | ||
581 | *p++ = '\n'; | ||
582 | |||
583 | /* output content */ | ||
584 | for (y = 0; y < FLDSIZE_Y; y++) { | ||
585 | *p++ = '|'; | ||
586 | for (x = 0; x < FLDSIZE_X; x++) | ||
587 | *p++ = augmentation_string[MIN(field[x][y], len)]; | ||
588 | *p++ = '|'; | ||
589 | *p++ = '\n'; | ||
590 | } | ||
591 | |||
592 | /* output lower border */ | ||
593 | *p++ = '+'; | ||
594 | for (i = 0; i < FLDSIZE_X; i++) | ||
595 | *p++ = '-'; | ||
596 | *p++ = '+'; | ||
597 | |||
598 | return retval; | ||
599 | } | ||
600 | |||
601 | char * | ||
602 | key_fingerprint(const Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep) | ||
603 | { | ||
604 | char *retval = NULL; | ||
605 | u_char *dgst_raw; | ||
606 | u_int dgst_raw_len; | ||
607 | |||
608 | dgst_raw = key_fingerprint_raw(k, dgst_type, &dgst_raw_len); | ||
609 | if (!dgst_raw) | ||
610 | fatal("key_fingerprint: null from key_fingerprint_raw()"); | ||
611 | switch (dgst_rep) { | ||
612 | case SSH_FP_HEX: | ||
613 | retval = key_fingerprint_hex(dgst_raw, dgst_raw_len); | ||
614 | break; | ||
615 | case SSH_FP_BUBBLEBABBLE: | ||
616 | retval = key_fingerprint_bubblebabble(dgst_raw, dgst_raw_len); | ||
617 | break; | ||
618 | case SSH_FP_RANDOMART: | ||
619 | retval = key_fingerprint_randomart(dgst_raw, dgst_raw_len, k); | ||
620 | break; | ||
621 | default: | ||
622 | fatal("key_fingerprint: bad digest representation %d", | ||
623 | dgst_rep); | ||
624 | break; | ||
625 | } | ||
626 | explicit_bzero(dgst_raw, dgst_raw_len); | ||
627 | free(dgst_raw); | ||
628 | return retval; | ||
629 | } | ||
630 | |||
631 | /* | ||
632 | * Reads a multiple-precision integer in decimal from the buffer, and advances | ||
633 | * the pointer. The integer must already be initialized. This function is | ||
634 | * permitted to modify the buffer. This leaves *cpp to point just beyond the | ||
635 | * last processed (and maybe modified) character. Note that this may modify | ||
636 | * the buffer containing the number. | ||
637 | */ | ||
638 | static int | ||
639 | read_bignum(char **cpp, BIGNUM * value) | ||
640 | { | ||
641 | char *cp = *cpp; | ||
642 | int old; | ||
643 | |||
644 | /* Skip any leading whitespace. */ | ||
645 | for (; *cp == ' ' || *cp == '\t'; cp++) | ||
646 | ; | ||
647 | |||
648 | /* Check that it begins with a decimal digit. */ | ||
649 | if (*cp < '0' || *cp > '9') | ||
650 | return 0; | ||
651 | |||
652 | /* Save starting position. */ | ||
653 | *cpp = cp; | ||
654 | |||
655 | /* Move forward until all decimal digits skipped. */ | ||
656 | for (; *cp >= '0' && *cp <= '9'; cp++) | ||
657 | ; | ||
658 | |||
659 | /* Save the old terminating character, and replace it by \0. */ | ||
660 | old = *cp; | ||
661 | *cp = 0; | ||
662 | |||
663 | /* Parse the number. */ | ||
664 | if (BN_dec2bn(&value, *cpp) == 0) | ||
665 | return 0; | ||
666 | |||
667 | /* Restore old terminating character. */ | ||
668 | *cp = old; | ||
669 | |||
670 | /* Move beyond the number and return success. */ | ||
671 | *cpp = cp; | ||
672 | return 1; | ||
673 | } | ||
674 | |||
675 | static int | ||
676 | write_bignum(FILE *f, BIGNUM *num) | ||
677 | { | ||
678 | char *buf = BN_bn2dec(num); | ||
679 | if (buf == NULL) { | ||
680 | error("write_bignum: BN_bn2dec() failed"); | ||
681 | return 0; | ||
682 | } | ||
683 | fprintf(f, " %s", buf); | ||
684 | OPENSSL_free(buf); | ||
685 | return 1; | ||
686 | } | 58 | } |
687 | 59 | ||
688 | /* returns 1 ok, -1 error */ | ||
689 | int | 60 | int |
690 | key_read(Key *ret, char **cpp) | 61 | key_read(Key *ret, char **cpp) |
691 | { | 62 | { |
692 | Key *k; | 63 | return sshkey_read(ret, cpp) == 0 ? 1 : -1; |
693 | int success = -1; | ||
694 | char *cp, *space; | ||
695 | int len, n, type; | ||
696 | u_int bits; | ||
697 | u_char *blob; | ||
698 | #ifdef OPENSSL_HAS_ECC | ||
699 | int curve_nid = -1; | ||
700 | #endif | ||
701 | |||
702 | cp = *cpp; | ||
703 | |||
704 | switch (ret->type) { | ||
705 | case KEY_RSA1: | ||
706 | /* Get number of bits. */ | ||
707 | if (*cp < '0' || *cp > '9') | ||
708 | return -1; /* Bad bit count... */ | ||
709 | for (bits = 0; *cp >= '0' && *cp <= '9'; cp++) | ||
710 | bits = 10 * bits + *cp - '0'; | ||
711 | if (bits == 0) | ||
712 | return -1; | ||
713 | *cpp = cp; | ||
714 | /* Get public exponent, public modulus. */ | ||
715 | if (!read_bignum(cpp, ret->rsa->e)) | ||
716 | return -1; | ||
717 | if (!read_bignum(cpp, ret->rsa->n)) | ||
718 | return -1; | ||
719 | /* validate the claimed number of bits */ | ||
720 | if ((u_int)BN_num_bits(ret->rsa->n) != bits) { | ||
721 | verbose("key_read: claimed key size %d does not match " | ||
722 | "actual %d", bits, BN_num_bits(ret->rsa->n)); | ||
723 | return -1; | ||
724 | } | ||
725 | success = 1; | ||
726 | break; | ||
727 | case KEY_UNSPEC: | ||
728 | case KEY_RSA: | ||
729 | case KEY_DSA: | ||
730 | case KEY_ECDSA: | ||
731 | case KEY_ED25519: | ||
732 | case KEY_DSA_CERT_V00: | ||
733 | case KEY_RSA_CERT_V00: | ||
734 | case KEY_DSA_CERT: | ||
735 | case KEY_ECDSA_CERT: | ||
736 | case KEY_RSA_CERT: | ||
737 | case KEY_ED25519_CERT: | ||
738 | space = strchr(cp, ' '); | ||
739 | if (space == NULL) { | ||
740 | debug3("key_read: missing whitespace"); | ||
741 | return -1; | ||
742 | } | ||
743 | *space = '\0'; | ||
744 | type = key_type_from_name(cp); | ||
745 | #ifdef OPENSSL_HAS_ECC | ||
746 | if (key_type_plain(type) == KEY_ECDSA && | ||
747 | (curve_nid = key_ecdsa_nid_from_name(cp)) == -1) { | ||
748 | debug("key_read: invalid curve"); | ||
749 | return -1; | ||
750 | } | ||
751 | #endif | ||
752 | *space = ' '; | ||
753 | if (type == KEY_UNSPEC) { | ||
754 | debug3("key_read: missing keytype"); | ||
755 | return -1; | ||
756 | } | ||
757 | cp = space+1; | ||
758 | if (*cp == '\0') { | ||
759 | debug3("key_read: short string"); | ||
760 | return -1; | ||
761 | } | ||
762 | if (ret->type == KEY_UNSPEC) { | ||
763 | ret->type = type; | ||
764 | } else if (ret->type != type) { | ||
765 | /* is a key, but different type */ | ||
766 | debug3("key_read: type mismatch"); | ||
767 | return -1; | ||
768 | } | ||
769 | len = 2*strlen(cp); | ||
770 | blob = xmalloc(len); | ||
771 | n = uudecode(cp, blob, len); | ||
772 | if (n < 0) { | ||
773 | error("key_read: uudecode %s failed", cp); | ||
774 | free(blob); | ||
775 | return -1; | ||
776 | } | ||
777 | k = key_from_blob(blob, (u_int)n); | ||
778 | free(blob); | ||
779 | if (k == NULL) { | ||
780 | error("key_read: key_from_blob %s failed", cp); | ||
781 | return -1; | ||
782 | } | ||
783 | if (k->type != type) { | ||
784 | error("key_read: type mismatch: encoding error"); | ||
785 | key_free(k); | ||
786 | return -1; | ||
787 | } | ||
788 | #ifdef OPENSSL_HAS_ECC | ||
789 | if (key_type_plain(type) == KEY_ECDSA && | ||
790 | curve_nid != k->ecdsa_nid) { | ||
791 | error("key_read: type mismatch: EC curve mismatch"); | ||
792 | key_free(k); | ||
793 | return -1; | ||
794 | } | ||
795 | #endif | ||
796 | /*XXXX*/ | ||
797 | if (key_is_cert(ret)) { | ||
798 | if (!key_is_cert(k)) { | ||
799 | error("key_read: loaded key is not a cert"); | ||
800 | key_free(k); | ||
801 | return -1; | ||
802 | } | ||
803 | if (ret->cert != NULL) | ||
804 | cert_free(ret->cert); | ||
805 | ret->cert = k->cert; | ||
806 | k->cert = NULL; | ||
807 | } | ||
808 | if (key_type_plain(ret->type) == KEY_RSA) { | ||
809 | if (ret->rsa != NULL) | ||
810 | RSA_free(ret->rsa); | ||
811 | ret->rsa = k->rsa; | ||
812 | k->rsa = NULL; | ||
813 | #ifdef DEBUG_PK | ||
814 | RSA_print_fp(stderr, ret->rsa, 8); | ||
815 | #endif | ||
816 | } | ||
817 | if (key_type_plain(ret->type) == KEY_DSA) { | ||
818 | if (ret->dsa != NULL) | ||
819 | DSA_free(ret->dsa); | ||
820 | ret->dsa = k->dsa; | ||
821 | k->dsa = NULL; | ||
822 | #ifdef DEBUG_PK | ||
823 | DSA_print_fp(stderr, ret->dsa, 8); | ||
824 | #endif | ||
825 | } | ||
826 | #ifdef OPENSSL_HAS_ECC | ||
827 | if (key_type_plain(ret->type) == KEY_ECDSA) { | ||
828 | if (ret->ecdsa != NULL) | ||
829 | EC_KEY_free(ret->ecdsa); | ||
830 | ret->ecdsa = k->ecdsa; | ||
831 | ret->ecdsa_nid = k->ecdsa_nid; | ||
832 | k->ecdsa = NULL; | ||
833 | k->ecdsa_nid = -1; | ||
834 | #ifdef DEBUG_PK | ||
835 | key_dump_ec_key(ret->ecdsa); | ||
836 | #endif | ||
837 | } | ||
838 | #endif | ||
839 | if (key_type_plain(ret->type) == KEY_ED25519) { | ||
840 | free(ret->ed25519_pk); | ||
841 | ret->ed25519_pk = k->ed25519_pk; | ||
842 | k->ed25519_pk = NULL; | ||
843 | #ifdef DEBUG_PK | ||
844 | /* XXX */ | ||
845 | #endif | ||
846 | } | ||
847 | success = 1; | ||
848 | /*XXXX*/ | ||
849 | key_free(k); | ||
850 | if (success != 1) | ||
851 | break; | ||
852 | /* advance cp: skip whitespace and data */ | ||
853 | while (*cp == ' ' || *cp == '\t') | ||
854 | cp++; | ||
855 | while (*cp != '\0' && *cp != ' ' && *cp != '\t') | ||
856 | cp++; | ||
857 | *cpp = cp; | ||
858 | break; | ||
859 | default: | ||
860 | fatal("key_read: bad key type: %d", ret->type); | ||
861 | break; | ||
862 | } | ||
863 | return success; | ||
864 | } | 64 | } |
865 | 65 | ||
866 | int | 66 | int |
867 | key_write(const Key *key, FILE *f) | 67 | key_write(const Key *key, FILE *f) |
868 | { | 68 | { |
869 | int n, success = 0; | 69 | return sshkey_write(key, f) == 0 ? 1 : 0; |
870 | u_int len, bits = 0; | ||
871 | u_char *blob; | ||
872 | char *uu; | ||
873 | |||
874 | if (key_is_cert(key)) { | ||
875 | if (key->cert == NULL) { | ||
876 | error("%s: no cert data", __func__); | ||
877 | return 0; | ||
878 | } | ||
879 | if (buffer_len(&key->cert->certblob) == 0) { | ||
880 | error("%s: no signed certificate blob", __func__); | ||
881 | return 0; | ||
882 | } | ||
883 | } | ||
884 | |||
885 | switch (key->type) { | ||
886 | case KEY_RSA1: | ||
887 | if (key->rsa == NULL) | ||
888 | return 0; | ||
889 | /* size of modulus 'n' */ | ||
890 | bits = BN_num_bits(key->rsa->n); | ||
891 | fprintf(f, "%u", bits); | ||
892 | if (write_bignum(f, key->rsa->e) && | ||
893 | write_bignum(f, key->rsa->n)) | ||
894 | return 1; | ||
895 | error("key_write: failed for RSA key"); | ||
896 | return 0; | ||
897 | case KEY_DSA: | ||
898 | case KEY_DSA_CERT_V00: | ||
899 | case KEY_DSA_CERT: | ||
900 | if (key->dsa == NULL) | ||
901 | return 0; | ||
902 | break; | ||
903 | #ifdef OPENSSL_HAS_ECC | ||
904 | case KEY_ECDSA: | ||
905 | case KEY_ECDSA_CERT: | ||
906 | if (key->ecdsa == NULL) | ||
907 | return 0; | ||
908 | break; | ||
909 | #endif | ||
910 | case KEY_ED25519: | ||
911 | case KEY_ED25519_CERT: | ||
912 | if (key->ed25519_pk == NULL) | ||
913 | return 0; | ||
914 | break; | ||
915 | case KEY_RSA: | ||
916 | case KEY_RSA_CERT_V00: | ||
917 | case KEY_RSA_CERT: | ||
918 | if (key->rsa == NULL) | ||
919 | return 0; | ||
920 | break; | ||
921 | default: | ||
922 | return 0; | ||
923 | } | ||
924 | |||
925 | key_to_blob(key, &blob, &len); | ||
926 | uu = xmalloc(2*len); | ||
927 | n = uuencode(blob, len, uu, 2*len); | ||
928 | if (n > 0) { | ||
929 | fprintf(f, "%s %s", key_ssh_name(key), uu); | ||
930 | success = 1; | ||
931 | } | ||
932 | free(blob); | ||
933 | free(uu); | ||
934 | |||
935 | return success; | ||
936 | } | ||
937 | |||
938 | const char * | ||
939 | key_cert_type(const Key *k) | ||
940 | { | ||
941 | switch (k->cert->type) { | ||
942 | case SSH2_CERT_TYPE_USER: | ||
943 | return "user"; | ||
944 | case SSH2_CERT_TYPE_HOST: | ||
945 | return "host"; | ||
946 | default: | ||
947 | return "unknown"; | ||
948 | } | ||
949 | } | ||
950 | |||
951 | struct keytype { | ||
952 | char *name; | ||
953 | char *shortname; | ||
954 | int type; | ||
955 | int nid; | ||
956 | int cert; | ||
957 | }; | ||
958 | static const struct keytype keytypes[] = { | ||
959 | { NULL, "RSA1", KEY_RSA1, 0, 0 }, | ||
960 | { "ssh-rsa", "RSA", KEY_RSA, 0, 0 }, | ||
961 | { "ssh-dss", "DSA", KEY_DSA, 0, 0 }, | ||
962 | { "ssh-ed25519", "ED25519", KEY_ED25519, 0, 0 }, | ||
963 | #ifdef OPENSSL_HAS_ECC | ||
964 | { "ecdsa-sha2-nistp256", "ECDSA", KEY_ECDSA, NID_X9_62_prime256v1, 0 }, | ||
965 | { "ecdsa-sha2-nistp384", "ECDSA", KEY_ECDSA, NID_secp384r1, 0 }, | ||
966 | # ifdef OPENSSL_HAS_NISTP521 | ||
967 | { "ecdsa-sha2-nistp521", "ECDSA", KEY_ECDSA, NID_secp521r1, 0 }, | ||
968 | # endif | ||
969 | #endif /* OPENSSL_HAS_ECC */ | ||
970 | { "ssh-rsa-cert-v01@openssh.com", "RSA-CERT", KEY_RSA_CERT, 0, 1 }, | ||
971 | { "ssh-dss-cert-v01@openssh.com", "DSA-CERT", KEY_DSA_CERT, 0, 1 }, | ||
972 | #ifdef OPENSSL_HAS_ECC | ||
973 | { "ecdsa-sha2-nistp256-cert-v01@openssh.com", "ECDSA-CERT", | ||
974 | KEY_ECDSA_CERT, NID_X9_62_prime256v1, 1 }, | ||
975 | { "ecdsa-sha2-nistp384-cert-v01@openssh.com", "ECDSA-CERT", | ||
976 | KEY_ECDSA_CERT, NID_secp384r1, 1 }, | ||
977 | # ifdef OPENSSL_HAS_NISTP521 | ||
978 | { "ecdsa-sha2-nistp521-cert-v01@openssh.com", "ECDSA-CERT", | ||
979 | KEY_ECDSA_CERT, NID_secp521r1, 1 }, | ||
980 | # endif | ||
981 | #endif /* OPENSSL_HAS_ECC */ | ||
982 | { "ssh-rsa-cert-v00@openssh.com", "RSA-CERT-V00", | ||
983 | KEY_RSA_CERT_V00, 0, 1 }, | ||
984 | { "ssh-dss-cert-v00@openssh.com", "DSA-CERT-V00", | ||
985 | KEY_DSA_CERT_V00, 0, 1 }, | ||
986 | { "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT", | ||
987 | KEY_ED25519_CERT, 0, 1 }, | ||
988 | { "null", "null", KEY_NULL, 0, 0 }, | ||
989 | { NULL, NULL, -1, -1, 0 } | ||
990 | }; | ||
991 | |||
992 | const char * | ||
993 | key_type(const Key *k) | ||
994 | { | ||
995 | const struct keytype *kt; | ||
996 | |||
997 | for (kt = keytypes; kt->type != -1; kt++) { | ||
998 | if (kt->type == k->type) | ||
999 | return kt->shortname; | ||
1000 | } | ||
1001 | return "unknown"; | ||
1002 | } | ||
1003 | |||
1004 | static const char * | ||
1005 | key_ssh_name_from_type_nid(int type, int nid) | ||
1006 | { | ||
1007 | const struct keytype *kt; | ||
1008 | |||
1009 | for (kt = keytypes; kt->type != -1; kt++) { | ||
1010 | if (kt->type == type && (kt->nid == 0 || kt->nid == nid)) | ||
1011 | return kt->name; | ||
1012 | } | ||
1013 | return "ssh-unknown"; | ||
1014 | } | ||
1015 | |||
1016 | const char * | ||
1017 | key_ssh_name(const Key *k) | ||
1018 | { | ||
1019 | return key_ssh_name_from_type_nid(k->type, k->ecdsa_nid); | ||
1020 | } | ||
1021 | |||
1022 | const char * | ||
1023 | key_ssh_name_plain(const Key *k) | ||
1024 | { | ||
1025 | return key_ssh_name_from_type_nid(key_type_plain(k->type), | ||
1026 | k->ecdsa_nid); | ||
1027 | } | ||
1028 | |||
1029 | int | ||
1030 | key_type_from_name(char *name) | ||
1031 | { | ||
1032 | const struct keytype *kt; | ||
1033 | |||
1034 | for (kt = keytypes; kt->type != -1; kt++) { | ||
1035 | /* Only allow shortname matches for plain key types */ | ||
1036 | if ((kt->name != NULL && strcmp(name, kt->name) == 0) || | ||
1037 | (!kt->cert && strcasecmp(kt->shortname, name) == 0)) | ||
1038 | return kt->type; | ||
1039 | } | ||
1040 | debug2("key_type_from_name: unknown key type '%s'", name); | ||
1041 | return KEY_UNSPEC; | ||
1042 | } | ||
1043 | |||
1044 | int | ||
1045 | key_ecdsa_nid_from_name(const char *name) | ||
1046 | { | ||
1047 | const struct keytype *kt; | ||
1048 | |||
1049 | for (kt = keytypes; kt->type != -1; kt++) { | ||
1050 | if (kt->type != KEY_ECDSA && kt->type != KEY_ECDSA_CERT) | ||
1051 | continue; | ||
1052 | if (kt->name != NULL && strcmp(name, kt->name) == 0) | ||
1053 | return kt->nid; | ||
1054 | } | ||
1055 | debug2("%s: unknown/non-ECDSA key type '%s'", __func__, name); | ||
1056 | return -1; | ||
1057 | } | ||
1058 | |||
1059 | char * | ||
1060 | key_alg_list(int certs_only, int plain_only) | ||
1061 | { | ||
1062 | char *ret = NULL; | ||
1063 | size_t nlen, rlen = 0; | ||
1064 | const struct keytype *kt; | ||
1065 | |||
1066 | for (kt = keytypes; kt->type != -1; kt++) { | ||
1067 | if (kt->name == NULL || kt->type == KEY_NULL) | ||
1068 | continue; | ||
1069 | if ((certs_only && !kt->cert) || (plain_only && kt->cert)) | ||
1070 | continue; | ||
1071 | if (ret != NULL) | ||
1072 | ret[rlen++] = '\n'; | ||
1073 | nlen = strlen(kt->name); | ||
1074 | ret = xrealloc(ret, 1, rlen + nlen + 2); | ||
1075 | memcpy(ret + rlen, kt->name, nlen + 1); | ||
1076 | rlen += nlen; | ||
1077 | } | ||
1078 | return ret; | ||
1079 | } | ||
1080 | |||
1081 | int | ||
1082 | key_type_is_cert(int type) | ||
1083 | { | ||
1084 | const struct keytype *kt; | ||
1085 | |||
1086 | for (kt = keytypes; kt->type != -1; kt++) { | ||
1087 | if (kt->type == type) | ||
1088 | return kt->cert; | ||
1089 | } | ||
1090 | return 0; | ||
1091 | } | ||
1092 | |||
1093 | static int | ||
1094 | key_type_is_valid_ca(int type) | ||
1095 | { | ||
1096 | switch (type) { | ||
1097 | case KEY_RSA: | ||
1098 | case KEY_DSA: | ||
1099 | case KEY_ECDSA: | ||
1100 | case KEY_ED25519: | ||
1101 | return 1; | ||
1102 | default: | ||
1103 | return 0; | ||
1104 | } | ||
1105 | } | ||
1106 | |||
1107 | u_int | ||
1108 | key_size(const Key *k) | ||
1109 | { | ||
1110 | switch (k->type) { | ||
1111 | case KEY_RSA1: | ||
1112 | case KEY_RSA: | ||
1113 | case KEY_RSA_CERT_V00: | ||
1114 | case KEY_RSA_CERT: | ||
1115 | return BN_num_bits(k->rsa->n); | ||
1116 | case KEY_DSA: | ||
1117 | case KEY_DSA_CERT_V00: | ||
1118 | case KEY_DSA_CERT: | ||
1119 | return BN_num_bits(k->dsa->p); | ||
1120 | case KEY_ED25519: | ||
1121 | return 256; /* XXX */ | ||
1122 | #ifdef OPENSSL_HAS_ECC | ||
1123 | case KEY_ECDSA: | ||
1124 | case KEY_ECDSA_CERT: | ||
1125 | return key_curve_nid_to_bits(k->ecdsa_nid); | ||
1126 | #endif | ||
1127 | } | ||
1128 | return 0; | ||
1129 | } | ||
1130 | |||
1131 | static RSA * | ||
1132 | rsa_generate_private_key(u_int bits) | ||
1133 | { | ||
1134 | RSA *private = RSA_new(); | ||
1135 | BIGNUM *f4 = BN_new(); | ||
1136 | |||
1137 | if (private == NULL) | ||
1138 | fatal("%s: RSA_new failed", __func__); | ||
1139 | if (f4 == NULL) | ||
1140 | fatal("%s: BN_new failed", __func__); | ||
1141 | if (!BN_set_word(f4, RSA_F4)) | ||
1142 | fatal("%s: BN_new failed", __func__); | ||
1143 | if (!RSA_generate_key_ex(private, bits, f4, NULL)) | ||
1144 | fatal("%s: key generation failed.", __func__); | ||
1145 | BN_free(f4); | ||
1146 | return private; | ||
1147 | } | ||
1148 | |||
1149 | static DSA* | ||
1150 | dsa_generate_private_key(u_int bits) | ||
1151 | { | ||
1152 | DSA *private = DSA_new(); | ||
1153 | |||
1154 | if (private == NULL) | ||
1155 | fatal("%s: DSA_new failed", __func__); | ||
1156 | if (!DSA_generate_parameters_ex(private, bits, NULL, 0, NULL, | ||
1157 | NULL, NULL)) | ||
1158 | fatal("%s: DSA_generate_parameters failed", __func__); | ||
1159 | if (!DSA_generate_key(private)) | ||
1160 | fatal("%s: DSA_generate_key failed.", __func__); | ||
1161 | return private; | ||
1162 | } | ||
1163 | |||
1164 | int | ||
1165 | key_ecdsa_bits_to_nid(int bits) | ||
1166 | { | ||
1167 | switch (bits) { | ||
1168 | #ifdef OPENSSL_HAS_ECC | ||
1169 | case 256: | ||
1170 | return NID_X9_62_prime256v1; | ||
1171 | case 384: | ||
1172 | return NID_secp384r1; | ||
1173 | # ifdef OPENSSL_HAS_NISTP521 | ||
1174 | case 521: | ||
1175 | return NID_secp521r1; | ||
1176 | # endif | ||
1177 | #endif | ||
1178 | default: | ||
1179 | return -1; | ||
1180 | } | ||
1181 | } | ||
1182 | |||
1183 | #ifdef OPENSSL_HAS_ECC | ||
1184 | int | ||
1185 | key_ecdsa_key_to_nid(EC_KEY *k) | ||
1186 | { | ||
1187 | EC_GROUP *eg; | ||
1188 | int nids[] = { | ||
1189 | NID_X9_62_prime256v1, | ||
1190 | NID_secp384r1, | ||
1191 | # ifdef OPENSSL_HAS_NISTP521 | ||
1192 | NID_secp521r1, | ||
1193 | # endif | ||
1194 | -1 | ||
1195 | }; | ||
1196 | int nid; | ||
1197 | u_int i; | ||
1198 | BN_CTX *bnctx; | ||
1199 | const EC_GROUP *g = EC_KEY_get0_group(k); | ||
1200 | |||
1201 | /* | ||
1202 | * The group may be stored in a ASN.1 encoded private key in one of two | ||
1203 | * ways: as a "named group", which is reconstituted by ASN.1 object ID | ||
1204 | * or explicit group parameters encoded into the key blob. Only the | ||
1205 | * "named group" case sets the group NID for us, but we can figure | ||
1206 | * it out for the other case by comparing against all the groups that | ||
1207 | * are supported. | ||
1208 | */ | ||
1209 | if ((nid = EC_GROUP_get_curve_name(g)) > 0) | ||
1210 | return nid; | ||
1211 | if ((bnctx = BN_CTX_new()) == NULL) | ||
1212 | fatal("%s: BN_CTX_new() failed", __func__); | ||
1213 | for (i = 0; nids[i] != -1; i++) { | ||
1214 | if ((eg = EC_GROUP_new_by_curve_name(nids[i])) == NULL) | ||
1215 | fatal("%s: EC_GROUP_new_by_curve_name failed", | ||
1216 | __func__); | ||
1217 | if (EC_GROUP_cmp(g, eg, bnctx) == 0) | ||
1218 | break; | ||
1219 | EC_GROUP_free(eg); | ||
1220 | } | ||
1221 | BN_CTX_free(bnctx); | ||
1222 | debug3("%s: nid = %d", __func__, nids[i]); | ||
1223 | if (nids[i] != -1) { | ||
1224 | /* Use the group with the NID attached */ | ||
1225 | EC_GROUP_set_asn1_flag(eg, OPENSSL_EC_NAMED_CURVE); | ||
1226 | if (EC_KEY_set_group(k, eg) != 1) | ||
1227 | fatal("%s: EC_KEY_set_group", __func__); | ||
1228 | } | ||
1229 | return nids[i]; | ||
1230 | } | ||
1231 | |||
1232 | static EC_KEY* | ||
1233 | ecdsa_generate_private_key(u_int bits, int *nid) | ||
1234 | { | ||
1235 | EC_KEY *private; | ||
1236 | |||
1237 | if ((*nid = key_ecdsa_bits_to_nid(bits)) == -1) | ||
1238 | fatal("%s: invalid key length", __func__); | ||
1239 | if ((private = EC_KEY_new_by_curve_name(*nid)) == NULL) | ||
1240 | fatal("%s: EC_KEY_new_by_curve_name failed", __func__); | ||
1241 | if (EC_KEY_generate_key(private) != 1) | ||
1242 | fatal("%s: EC_KEY_generate_key failed", __func__); | ||
1243 | EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE); | ||
1244 | return private; | ||
1245 | } | 70 | } |
1246 | #endif /* OPENSSL_HAS_ECC */ | ||
1247 | 71 | ||
1248 | Key * | 72 | Key * |
1249 | key_generate(int type, u_int bits) | 73 | key_generate(int type, u_int bits) |
1250 | { | 74 | { |
1251 | Key *k = key_new(KEY_UNSPEC); | 75 | int r; |
1252 | switch (type) { | 76 | Key *ret = NULL; |
1253 | case KEY_DSA: | 77 | |
1254 | k->dsa = dsa_generate_private_key(bits); | 78 | if ((r = sshkey_generate(type, bits, &ret)) != 0) |
1255 | break; | 79 | fatal("%s: %s", __func__, ssh_err(r)); |
1256 | #ifdef OPENSSL_HAS_ECC | 80 | return ret; |
1257 | case KEY_ECDSA: | ||
1258 | k->ecdsa = ecdsa_generate_private_key(bits, &k->ecdsa_nid); | ||
1259 | break; | ||
1260 | #endif | ||
1261 | case KEY_RSA: | ||
1262 | case KEY_RSA1: | ||
1263 | k->rsa = rsa_generate_private_key(bits); | ||
1264 | break; | ||
1265 | case KEY_ED25519: | ||
1266 | k->ed25519_pk = xmalloc(ED25519_PK_SZ); | ||
1267 | k->ed25519_sk = xmalloc(ED25519_SK_SZ); | ||
1268 | crypto_sign_ed25519_keypair(k->ed25519_pk, k->ed25519_sk); | ||
1269 | break; | ||
1270 | case KEY_RSA_CERT_V00: | ||
1271 | case KEY_DSA_CERT_V00: | ||
1272 | case KEY_RSA_CERT: | ||
1273 | case KEY_DSA_CERT: | ||
1274 | fatal("key_generate: cert keys cannot be generated directly"); | ||
1275 | default: | ||
1276 | fatal("key_generate: unknown type %d", type); | ||
1277 | } | ||
1278 | k->type = type; | ||
1279 | return k; | ||
1280 | } | 81 | } |
1281 | 82 | ||
1282 | void | 83 | void |
1283 | key_cert_copy(const Key *from_key, struct Key *to_key) | 84 | key_cert_copy(const Key *from_key, Key *to_key) |
1284 | { | 85 | { |
1285 | u_int i; | 86 | int r; |
1286 | const struct KeyCert *from; | ||
1287 | struct KeyCert *to; | ||
1288 | |||
1289 | if (to_key->cert != NULL) { | ||
1290 | cert_free(to_key->cert); | ||
1291 | to_key->cert = NULL; | ||
1292 | } | ||
1293 | 87 | ||
1294 | if ((from = from_key->cert) == NULL) | 88 | if ((r = sshkey_cert_copy(from_key, to_key)) != 0) |
1295 | return; | 89 | fatal("%s: %s", __func__, ssh_err(r)); |
1296 | |||
1297 | to = to_key->cert = cert_new(); | ||
1298 | |||
1299 | buffer_append(&to->certblob, buffer_ptr(&from->certblob), | ||
1300 | buffer_len(&from->certblob)); | ||
1301 | |||
1302 | buffer_append(&to->critical, | ||
1303 | buffer_ptr(&from->critical), buffer_len(&from->critical)); | ||
1304 | buffer_append(&to->extensions, | ||
1305 | buffer_ptr(&from->extensions), buffer_len(&from->extensions)); | ||
1306 | |||
1307 | to->serial = from->serial; | ||
1308 | to->type = from->type; | ||
1309 | to->key_id = from->key_id == NULL ? NULL : xstrdup(from->key_id); | ||
1310 | to->valid_after = from->valid_after; | ||
1311 | to->valid_before = from->valid_before; | ||
1312 | to->signature_key = from->signature_key == NULL ? | ||
1313 | NULL : key_from_private(from->signature_key); | ||
1314 | |||
1315 | to->nprincipals = from->nprincipals; | ||
1316 | if (to->nprincipals > CERT_MAX_PRINCIPALS) | ||
1317 | fatal("%s: nprincipals (%u) > CERT_MAX_PRINCIPALS (%u)", | ||
1318 | __func__, to->nprincipals, CERT_MAX_PRINCIPALS); | ||
1319 | if (to->nprincipals > 0) { | ||
1320 | to->principals = xcalloc(from->nprincipals, | ||
1321 | sizeof(*to->principals)); | ||
1322 | for (i = 0; i < to->nprincipals; i++) | ||
1323 | to->principals[i] = xstrdup(from->principals[i]); | ||
1324 | } | ||
1325 | } | 90 | } |
1326 | 91 | ||
1327 | Key * | 92 | Key * |
1328 | key_from_private(const Key *k) | 93 | key_from_private(const Key *k) |
1329 | { | 94 | { |
1330 | Key *n = NULL; | 95 | int r; |
1331 | switch (k->type) { | 96 | Key *ret = NULL; |
1332 | case KEY_DSA: | ||
1333 | case KEY_DSA_CERT_V00: | ||
1334 | case KEY_DSA_CERT: | ||
1335 | n = key_new(k->type); | ||
1336 | if ((BN_copy(n->dsa->p, k->dsa->p) == NULL) || | ||
1337 | (BN_copy(n->dsa->q, k->dsa->q) == NULL) || | ||
1338 | (BN_copy(n->dsa->g, k->dsa->g) == NULL) || | ||
1339 | (BN_copy(n->dsa->pub_key, k->dsa->pub_key) == NULL)) | ||
1340 | fatal("key_from_private: BN_copy failed"); | ||
1341 | break; | ||
1342 | #ifdef OPENSSL_HAS_ECC | ||
1343 | case KEY_ECDSA: | ||
1344 | case KEY_ECDSA_CERT: | ||
1345 | n = key_new(k->type); | ||
1346 | n->ecdsa_nid = k->ecdsa_nid; | ||
1347 | if ((n->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid)) == NULL) | ||
1348 | fatal("%s: EC_KEY_new_by_curve_name failed", __func__); | ||
1349 | if (EC_KEY_set_public_key(n->ecdsa, | ||
1350 | EC_KEY_get0_public_key(k->ecdsa)) != 1) | ||
1351 | fatal("%s: EC_KEY_set_public_key failed", __func__); | ||
1352 | break; | ||
1353 | #endif | ||
1354 | case KEY_RSA: | ||
1355 | case KEY_RSA1: | ||
1356 | case KEY_RSA_CERT_V00: | ||
1357 | case KEY_RSA_CERT: | ||
1358 | n = key_new(k->type); | ||
1359 | if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) || | ||
1360 | (BN_copy(n->rsa->e, k->rsa->e) == NULL)) | ||
1361 | fatal("key_from_private: BN_copy failed"); | ||
1362 | break; | ||
1363 | case KEY_ED25519: | ||
1364 | case KEY_ED25519_CERT: | ||
1365 | n = key_new(k->type); | ||
1366 | if (k->ed25519_pk != NULL) { | ||
1367 | n->ed25519_pk = xmalloc(ED25519_PK_SZ); | ||
1368 | memcpy(n->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ); | ||
1369 | } | ||
1370 | break; | ||
1371 | default: | ||
1372 | fatal("key_from_private: unknown type %d", k->type); | ||
1373 | break; | ||
1374 | } | ||
1375 | if (key_is_cert(k)) | ||
1376 | key_cert_copy(k, n); | ||
1377 | return n; | ||
1378 | } | ||
1379 | |||
1380 | int | ||
1381 | key_names_valid2(const char *names) | ||
1382 | { | ||
1383 | char *s, *cp, *p; | ||
1384 | |||
1385 | if (names == NULL || strcmp(names, "") == 0) | ||
1386 | return 0; | ||
1387 | s = cp = xstrdup(names); | ||
1388 | for ((p = strsep(&cp, ",")); p && *p != '\0'; | ||
1389 | (p = strsep(&cp, ","))) { | ||
1390 | switch (key_type_from_name(p)) { | ||
1391 | case KEY_RSA1: | ||
1392 | case KEY_UNSPEC: | ||
1393 | free(s); | ||
1394 | return 0; | ||
1395 | } | ||
1396 | } | ||
1397 | debug3("key names ok: [%s]", names); | ||
1398 | free(s); | ||
1399 | return 1; | ||
1400 | } | ||
1401 | |||
1402 | static int | ||
1403 | cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) | ||
1404 | { | ||
1405 | u_char *principals, *critical, *exts, *sig_key, *sig; | ||
1406 | u_int signed_len, plen, clen, sklen, slen, kidlen, elen; | ||
1407 | Buffer tmp; | ||
1408 | char *principal; | ||
1409 | int ret = -1; | ||
1410 | int v00 = key->type == KEY_DSA_CERT_V00 || | ||
1411 | key->type == KEY_RSA_CERT_V00; | ||
1412 | |||
1413 | buffer_init(&tmp); | ||
1414 | |||
1415 | /* Copy the entire key blob for verification and later serialisation */ | ||
1416 | buffer_append(&key->cert->certblob, blob, blen); | ||
1417 | |||
1418 | elen = 0; /* Not touched for v00 certs */ | ||
1419 | principals = exts = critical = sig_key = sig = NULL; | ||
1420 | if ((!v00 && buffer_get_int64_ret(&key->cert->serial, b) != 0) || | ||
1421 | buffer_get_int_ret(&key->cert->type, b) != 0 || | ||
1422 | (key->cert->key_id = buffer_get_cstring_ret(b, &kidlen)) == NULL || | ||
1423 | (principals = buffer_get_string_ret(b, &plen)) == NULL || | ||
1424 | buffer_get_int64_ret(&key->cert->valid_after, b) != 0 || | ||
1425 | buffer_get_int64_ret(&key->cert->valid_before, b) != 0 || | ||
1426 | (critical = buffer_get_string_ret(b, &clen)) == NULL || | ||
1427 | (!v00 && (exts = buffer_get_string_ret(b, &elen)) == NULL) || | ||
1428 | (v00 && buffer_get_string_ptr_ret(b, NULL) == NULL) || /* nonce */ | ||
1429 | buffer_get_string_ptr_ret(b, NULL) == NULL || /* reserved */ | ||
1430 | (sig_key = buffer_get_string_ret(b, &sklen)) == NULL) { | ||
1431 | error("%s: parse error", __func__); | ||
1432 | goto out; | ||
1433 | } | ||
1434 | |||
1435 | /* Signature is left in the buffer so we can calculate this length */ | ||
1436 | signed_len = buffer_len(&key->cert->certblob) - buffer_len(b); | ||
1437 | |||
1438 | if ((sig = buffer_get_string_ret(b, &slen)) == NULL) { | ||
1439 | error("%s: parse error", __func__); | ||
1440 | goto out; | ||
1441 | } | ||
1442 | |||
1443 | if (key->cert->type != SSH2_CERT_TYPE_USER && | ||
1444 | key->cert->type != SSH2_CERT_TYPE_HOST) { | ||
1445 | error("Unknown certificate type %u", key->cert->type); | ||
1446 | goto out; | ||
1447 | } | ||
1448 | 97 | ||
1449 | buffer_append(&tmp, principals, plen); | 98 | if ((r = sshkey_from_private(k, &ret)) != 0) |
1450 | while (buffer_len(&tmp) > 0) { | 99 | fatal("%s: %s", __func__, ssh_err(r)); |
1451 | if (key->cert->nprincipals >= CERT_MAX_PRINCIPALS) { | ||
1452 | error("%s: Too many principals", __func__); | ||
1453 | goto out; | ||
1454 | } | ||
1455 | if ((principal = buffer_get_cstring_ret(&tmp, &plen)) == NULL) { | ||
1456 | error("%s: Principals data invalid", __func__); | ||
1457 | goto out; | ||
1458 | } | ||
1459 | key->cert->principals = xrealloc(key->cert->principals, | ||
1460 | key->cert->nprincipals + 1, sizeof(*key->cert->principals)); | ||
1461 | key->cert->principals[key->cert->nprincipals++] = principal; | ||
1462 | } | ||
1463 | |||
1464 | buffer_clear(&tmp); | ||
1465 | |||
1466 | buffer_append(&key->cert->critical, critical, clen); | ||
1467 | buffer_append(&tmp, critical, clen); | ||
1468 | /* validate structure */ | ||
1469 | while (buffer_len(&tmp) != 0) { | ||
1470 | if (buffer_get_string_ptr_ret(&tmp, NULL) == NULL || | ||
1471 | buffer_get_string_ptr_ret(&tmp, NULL) == NULL) { | ||
1472 | error("%s: critical option data invalid", __func__); | ||
1473 | goto out; | ||
1474 | } | ||
1475 | } | ||
1476 | buffer_clear(&tmp); | ||
1477 | |||
1478 | buffer_append(&key->cert->extensions, exts, elen); | ||
1479 | buffer_append(&tmp, exts, elen); | ||
1480 | /* validate structure */ | ||
1481 | while (buffer_len(&tmp) != 0) { | ||
1482 | if (buffer_get_string_ptr_ret(&tmp, NULL) == NULL || | ||
1483 | buffer_get_string_ptr_ret(&tmp, NULL) == NULL) { | ||
1484 | error("%s: extension data invalid", __func__); | ||
1485 | goto out; | ||
1486 | } | ||
1487 | } | ||
1488 | buffer_clear(&tmp); | ||
1489 | |||
1490 | if ((key->cert->signature_key = key_from_blob2(sig_key, sklen, 0)) | ||
1491 | == NULL) { | ||
1492 | error("%s: Signature key invalid", __func__); | ||
1493 | goto out; | ||
1494 | } | ||
1495 | if (!key_type_is_valid_ca(key->cert->signature_key->type)) { | ||
1496 | error("%s: Invalid signature key type %s (%d)", __func__, | ||
1497 | key_type(key->cert->signature_key), | ||
1498 | key->cert->signature_key->type); | ||
1499 | goto out; | ||
1500 | } | ||
1501 | |||
1502 | switch (key_verify(key->cert->signature_key, sig, slen, | ||
1503 | buffer_ptr(&key->cert->certblob), signed_len)) { | ||
1504 | case 1: | ||
1505 | ret = 0; | ||
1506 | break; /* Good signature */ | ||
1507 | case 0: | ||
1508 | error("%s: Invalid signature on certificate", __func__); | ||
1509 | goto out; | ||
1510 | case -1: | ||
1511 | error("%s: Certificate signature verification failed", | ||
1512 | __func__); | ||
1513 | goto out; | ||
1514 | } | ||
1515 | |||
1516 | out: | ||
1517 | buffer_free(&tmp); | ||
1518 | free(principals); | ||
1519 | free(critical); | ||
1520 | free(exts); | ||
1521 | free(sig_key); | ||
1522 | free(sig); | ||
1523 | return ret; | 100 | return ret; |
1524 | } | 101 | } |
1525 | 102 | ||
1526 | static Key * | 103 | static void |
1527 | key_from_blob2(const u_char *blob, u_int blen, int allow_cert) | 104 | fatal_on_fatal_errors(int r, const char *func, int extra_fatal) |
1528 | { | 105 | { |
1529 | Buffer b; | 106 | if (r == SSH_ERR_INTERNAL_ERROR || |
1530 | int rlen, type; | 107 | r == SSH_ERR_ALLOC_FAIL || |
1531 | u_int len; | 108 | (extra_fatal != 0 && r == extra_fatal)) |
1532 | char *ktype = NULL, *curve = NULL; | 109 | fatal("%s: %s", func, ssh_err(r)); |
1533 | u_char *pk = NULL; | ||
1534 | Key *key = NULL; | ||
1535 | #ifdef OPENSSL_HAS_ECC | ||
1536 | EC_POINT *q = NULL; | ||
1537 | int nid = -1; | ||
1538 | #endif | ||
1539 | |||
1540 | #ifdef DEBUG_PK | ||
1541 | dump_base64(stderr, blob, blen); | ||
1542 | #endif | ||
1543 | buffer_init(&b); | ||
1544 | buffer_append(&b, blob, blen); | ||
1545 | if ((ktype = buffer_get_cstring_ret(&b, NULL)) == NULL) { | ||
1546 | error("key_from_blob: can't read key type"); | ||
1547 | goto out; | ||
1548 | } | ||
1549 | |||
1550 | type = key_type_from_name(ktype); | ||
1551 | #ifdef OPENSSL_HAS_ECC | ||
1552 | if (key_type_plain(type) == KEY_ECDSA) | ||
1553 | nid = key_ecdsa_nid_from_name(ktype); | ||
1554 | #endif | ||
1555 | if (!allow_cert && key_type_is_cert(type)) { | ||
1556 | error("key_from_blob: certificate not allowed in this context"); | ||
1557 | goto out; | ||
1558 | } | ||
1559 | switch (type) { | ||
1560 | case KEY_RSA_CERT: | ||
1561 | (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */ | ||
1562 | /* FALLTHROUGH */ | ||
1563 | case KEY_RSA: | ||
1564 | case KEY_RSA_CERT_V00: | ||
1565 | key = key_new(type); | ||
1566 | if (buffer_get_bignum2_ret(&b, key->rsa->e) == -1 || | ||
1567 | buffer_get_bignum2_ret(&b, key->rsa->n) == -1) { | ||
1568 | error("key_from_blob: can't read rsa key"); | ||
1569 | badkey: | ||
1570 | key_free(key); | ||
1571 | key = NULL; | ||
1572 | goto out; | ||
1573 | } | ||
1574 | #ifdef DEBUG_PK | ||
1575 | RSA_print_fp(stderr, key->rsa, 8); | ||
1576 | #endif | ||
1577 | break; | ||
1578 | case KEY_DSA_CERT: | ||
1579 | (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */ | ||
1580 | /* FALLTHROUGH */ | ||
1581 | case KEY_DSA: | ||
1582 | case KEY_DSA_CERT_V00: | ||
1583 | key = key_new(type); | ||
1584 | if (buffer_get_bignum2_ret(&b, key->dsa->p) == -1 || | ||
1585 | buffer_get_bignum2_ret(&b, key->dsa->q) == -1 || | ||
1586 | buffer_get_bignum2_ret(&b, key->dsa->g) == -1 || | ||
1587 | buffer_get_bignum2_ret(&b, key->dsa->pub_key) == -1) { | ||
1588 | error("key_from_blob: can't read dsa key"); | ||
1589 | goto badkey; | ||
1590 | } | ||
1591 | #ifdef DEBUG_PK | ||
1592 | DSA_print_fp(stderr, key->dsa, 8); | ||
1593 | #endif | ||
1594 | break; | ||
1595 | #ifdef OPENSSL_HAS_ECC | ||
1596 | case KEY_ECDSA_CERT: | ||
1597 | (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */ | ||
1598 | /* FALLTHROUGH */ | ||
1599 | case KEY_ECDSA: | ||
1600 | key = key_new(type); | ||
1601 | key->ecdsa_nid = nid; | ||
1602 | if ((curve = buffer_get_string_ret(&b, NULL)) == NULL) { | ||
1603 | error("key_from_blob: can't read ecdsa curve"); | ||
1604 | goto badkey; | ||
1605 | } | ||
1606 | if (key->ecdsa_nid != key_curve_name_to_nid(curve)) { | ||
1607 | error("key_from_blob: ecdsa curve doesn't match type"); | ||
1608 | goto badkey; | ||
1609 | } | ||
1610 | if (key->ecdsa != NULL) | ||
1611 | EC_KEY_free(key->ecdsa); | ||
1612 | if ((key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid)) | ||
1613 | == NULL) | ||
1614 | fatal("key_from_blob: EC_KEY_new_by_curve_name failed"); | ||
1615 | if ((q = EC_POINT_new(EC_KEY_get0_group(key->ecdsa))) == NULL) | ||
1616 | fatal("key_from_blob: EC_POINT_new failed"); | ||
1617 | if (buffer_get_ecpoint_ret(&b, EC_KEY_get0_group(key->ecdsa), | ||
1618 | q) == -1) { | ||
1619 | error("key_from_blob: can't read ecdsa key point"); | ||
1620 | goto badkey; | ||
1621 | } | ||
1622 | if (key_ec_validate_public(EC_KEY_get0_group(key->ecdsa), | ||
1623 | q) != 0) | ||
1624 | goto badkey; | ||
1625 | if (EC_KEY_set_public_key(key->ecdsa, q) != 1) | ||
1626 | fatal("key_from_blob: EC_KEY_set_public_key failed"); | ||
1627 | #ifdef DEBUG_PK | ||
1628 | key_dump_ec_point(EC_KEY_get0_group(key->ecdsa), q); | ||
1629 | #endif | ||
1630 | break; | ||
1631 | #endif /* OPENSSL_HAS_ECC */ | ||
1632 | case KEY_ED25519_CERT: | ||
1633 | (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */ | ||
1634 | /* FALLTHROUGH */ | ||
1635 | case KEY_ED25519: | ||
1636 | if ((pk = buffer_get_string_ret(&b, &len)) == NULL) { | ||
1637 | error("key_from_blob: can't read ed25519 key"); | ||
1638 | goto badkey; | ||
1639 | } | ||
1640 | if (len != ED25519_PK_SZ) { | ||
1641 | error("key_from_blob: ed25519 len %d != %d", | ||
1642 | len, ED25519_PK_SZ); | ||
1643 | goto badkey; | ||
1644 | } | ||
1645 | key = key_new(type); | ||
1646 | key->ed25519_pk = pk; | ||
1647 | pk = NULL; | ||
1648 | break; | ||
1649 | case KEY_UNSPEC: | ||
1650 | key = key_new(type); | ||
1651 | break; | ||
1652 | default: | ||
1653 | error("key_from_blob: cannot handle type %s", ktype); | ||
1654 | goto out; | ||
1655 | } | ||
1656 | if (key_is_cert(key) && cert_parse(&b, key, blob, blen) == -1) { | ||
1657 | error("key_from_blob: can't parse cert data"); | ||
1658 | goto badkey; | ||
1659 | } | ||
1660 | rlen = buffer_len(&b); | ||
1661 | if (key != NULL && rlen != 0) | ||
1662 | error("key_from_blob: remaining bytes in key blob %d", rlen); | ||
1663 | out: | ||
1664 | free(ktype); | ||
1665 | free(curve); | ||
1666 | free(pk); | ||
1667 | #ifdef OPENSSL_HAS_ECC | ||
1668 | if (q != NULL) | ||
1669 | EC_POINT_free(q); | ||
1670 | #endif | ||
1671 | buffer_free(&b); | ||
1672 | return key; | ||
1673 | } | 110 | } |
1674 | 111 | ||
1675 | Key * | 112 | Key * |
1676 | key_from_blob(const u_char *blob, u_int blen) | 113 | key_from_blob(const u_char *blob, u_int blen) |
1677 | { | 114 | { |
1678 | return key_from_blob2(blob, blen, 1); | 115 | int r; |
116 | Key *ret = NULL; | ||
117 | |||
118 | if ((r = sshkey_from_blob(blob, blen, &ret)) != 0) { | ||
119 | fatal_on_fatal_errors(r, __func__, 0); | ||
120 | error("%s: %s", __func__, ssh_err(r)); | ||
121 | return NULL; | ||
122 | } | ||
123 | return ret; | ||
1679 | } | 124 | } |
1680 | 125 | ||
1681 | static int | 126 | int |
1682 | to_blob(const Key *key, u_char **blobp, u_int *lenp, int force_plain) | 127 | key_to_blob(const Key *key, u_char **blobp, u_int *lenp) |
1683 | { | 128 | { |
1684 | Buffer b; | 129 | u_char *blob; |
1685 | int len, type; | 130 | size_t blen; |
131 | int r; | ||
1686 | 132 | ||
1687 | if (blobp != NULL) | 133 | if (blobp != NULL) |
1688 | *blobp = NULL; | 134 | *blobp = NULL; |
1689 | if (lenp != NULL) | 135 | if (lenp != NULL) |
1690 | *lenp = 0; | 136 | *lenp = 0; |
1691 | if (key == NULL) { | 137 | if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) { |
1692 | error("key_to_blob: key == NULL"); | 138 | fatal_on_fatal_errors(r, __func__, 0); |
1693 | return 0; | 139 | error("%s: %s", __func__, ssh_err(r)); |
1694 | } | ||
1695 | buffer_init(&b); | ||
1696 | type = force_plain ? key_type_plain(key->type) : key->type; | ||
1697 | switch (type) { | ||
1698 | case KEY_DSA_CERT_V00: | ||
1699 | case KEY_RSA_CERT_V00: | ||
1700 | case KEY_DSA_CERT: | ||
1701 | case KEY_ECDSA_CERT: | ||
1702 | case KEY_RSA_CERT: | ||
1703 | case KEY_ED25519_CERT: | ||
1704 | /* Use the existing blob */ | ||
1705 | buffer_append(&b, buffer_ptr(&key->cert->certblob), | ||
1706 | buffer_len(&key->cert->certblob)); | ||
1707 | break; | ||
1708 | case KEY_DSA: | ||
1709 | buffer_put_cstring(&b, | ||
1710 | key_ssh_name_from_type_nid(type, key->ecdsa_nid)); | ||
1711 | buffer_put_bignum2(&b, key->dsa->p); | ||
1712 | buffer_put_bignum2(&b, key->dsa->q); | ||
1713 | buffer_put_bignum2(&b, key->dsa->g); | ||
1714 | buffer_put_bignum2(&b, key->dsa->pub_key); | ||
1715 | break; | ||
1716 | #ifdef OPENSSL_HAS_ECC | ||
1717 | case KEY_ECDSA: | ||
1718 | buffer_put_cstring(&b, | ||
1719 | key_ssh_name_from_type_nid(type, key->ecdsa_nid)); | ||
1720 | buffer_put_cstring(&b, key_curve_nid_to_name(key->ecdsa_nid)); | ||
1721 | buffer_put_ecpoint(&b, EC_KEY_get0_group(key->ecdsa), | ||
1722 | EC_KEY_get0_public_key(key->ecdsa)); | ||
1723 | break; | ||
1724 | #endif | ||
1725 | case KEY_RSA: | ||
1726 | buffer_put_cstring(&b, | ||
1727 | key_ssh_name_from_type_nid(type, key->ecdsa_nid)); | ||
1728 | buffer_put_bignum2(&b, key->rsa->e); | ||
1729 | buffer_put_bignum2(&b, key->rsa->n); | ||
1730 | break; | ||
1731 | case KEY_ED25519: | ||
1732 | buffer_put_cstring(&b, | ||
1733 | key_ssh_name_from_type_nid(type, key->ecdsa_nid)); | ||
1734 | buffer_put_string(&b, key->ed25519_pk, ED25519_PK_SZ); | ||
1735 | break; | ||
1736 | default: | ||
1737 | error("key_to_blob: unsupported key type %d", key->type); | ||
1738 | buffer_free(&b); | ||
1739 | return 0; | 140 | return 0; |
1740 | } | 141 | } |
1741 | len = buffer_len(&b); | 142 | if (blen > INT_MAX) |
143 | fatal("%s: giant len %zu", __func__, blen); | ||
144 | if (blobp != NULL) | ||
145 | *blobp = blob; | ||
1742 | if (lenp != NULL) | 146 | if (lenp != NULL) |
1743 | *lenp = len; | 147 | *lenp = blen; |
1744 | if (blobp != NULL) { | 148 | return blen; |
1745 | *blobp = xmalloc(len); | ||
1746 | memcpy(*blobp, buffer_ptr(&b), len); | ||
1747 | } | ||
1748 | explicit_bzero(buffer_ptr(&b), len); | ||
1749 | buffer_free(&b); | ||
1750 | return len; | ||
1751 | } | ||
1752 | |||
1753 | int | ||
1754 | key_to_blob(const Key *key, u_char **blobp, u_int *lenp) | ||
1755 | { | ||
1756 | return to_blob(key, blobp, lenp, 0); | ||
1757 | } | 149 | } |
1758 | 150 | ||
1759 | int | 151 | int |
1760 | key_sign( | 152 | key_sign(const Key *key, u_char **sigp, u_int *lenp, |
1761 | const Key *key, | ||
1762 | u_char **sigp, u_int *lenp, | ||
1763 | const u_char *data, u_int datalen) | 153 | const u_char *data, u_int datalen) |
1764 | { | 154 | { |
1765 | switch (key->type) { | 155 | int r; |
1766 | case KEY_DSA_CERT_V00: | 156 | u_char *sig; |
1767 | case KEY_DSA_CERT: | 157 | size_t siglen; |
1768 | case KEY_DSA: | 158 | |
1769 | return ssh_dss_sign(key, sigp, lenp, data, datalen); | 159 | if (sigp != NULL) |
1770 | #ifdef OPENSSL_HAS_ECC | 160 | *sigp = NULL; |
1771 | case KEY_ECDSA_CERT: | 161 | if (lenp != NULL) |
1772 | case KEY_ECDSA: | 162 | *lenp = 0; |
1773 | return ssh_ecdsa_sign(key, sigp, lenp, data, datalen); | 163 | if ((r = sshkey_sign(key, &sig, &siglen, |
1774 | #endif | 164 | data, datalen, datafellows)) != 0) { |
1775 | case KEY_RSA_CERT_V00: | 165 | fatal_on_fatal_errors(r, __func__, 0); |
1776 | case KEY_RSA_CERT: | 166 | error("%s: %s", __func__, ssh_err(r)); |
1777 | case KEY_RSA: | ||
1778 | return ssh_rsa_sign(key, sigp, lenp, data, datalen); | ||
1779 | case KEY_ED25519: | ||
1780 | case KEY_ED25519_CERT: | ||
1781 | return ssh_ed25519_sign(key, sigp, lenp, data, datalen); | ||
1782 | default: | ||
1783 | error("key_sign: invalid key type %d", key->type); | ||
1784 | return -1; | 167 | return -1; |
1785 | } | 168 | } |
169 | if (siglen > INT_MAX) | ||
170 | fatal("%s: giant len %zu", __func__, siglen); | ||
171 | if (sigp != NULL) | ||
172 | *sigp = sig; | ||
173 | if (lenp != NULL) | ||
174 | *lenp = siglen; | ||
175 | return 0; | ||
1786 | } | 176 | } |
1787 | 177 | ||
1788 | /* | ||
1789 | * key_verify returns 1 for a correct signature, 0 for an incorrect signature | ||
1790 | * and -1 on error. | ||
1791 | */ | ||
1792 | int | 178 | int |
1793 | key_verify( | 179 | key_verify(const Key *key, const u_char *signature, u_int signaturelen, |
1794 | const Key *key, | ||
1795 | const u_char *signature, u_int signaturelen, | ||
1796 | const u_char *data, u_int datalen) | 180 | const u_char *data, u_int datalen) |
1797 | { | 181 | { |
1798 | if (signaturelen == 0) | 182 | int r; |
1799 | return -1; | ||
1800 | 183 | ||
1801 | switch (key->type) { | 184 | if ((r = sshkey_verify(key, signature, signaturelen, |
1802 | case KEY_DSA_CERT_V00: | 185 | data, datalen, datafellows)) != 0) { |
1803 | case KEY_DSA_CERT: | 186 | fatal_on_fatal_errors(r, __func__, 0); |
1804 | case KEY_DSA: | 187 | error("%s: %s", __func__, ssh_err(r)); |
1805 | return ssh_dss_verify(key, signature, signaturelen, data, datalen); | 188 | return r == SSH_ERR_SIGNATURE_INVALID ? 0 : -1; |
1806 | #ifdef OPENSSL_HAS_ECC | ||
1807 | case KEY_ECDSA_CERT: | ||
1808 | case KEY_ECDSA: | ||
1809 | return ssh_ecdsa_verify(key, signature, signaturelen, data, datalen); | ||
1810 | #endif | ||
1811 | case KEY_RSA_CERT_V00: | ||
1812 | case KEY_RSA_CERT: | ||
1813 | case KEY_RSA: | ||
1814 | return ssh_rsa_verify(key, signature, signaturelen, data, datalen); | ||
1815 | case KEY_ED25519: | ||
1816 | case KEY_ED25519_CERT: | ||
1817 | return ssh_ed25519_verify(key, signature, signaturelen, data, datalen); | ||
1818 | default: | ||
1819 | error("key_verify: invalid key type %d", key->type); | ||
1820 | return -1; | ||
1821 | } | 189 | } |
190 | return 1; | ||
1822 | } | 191 | } |
1823 | 192 | ||
1824 | /* Converts a private to a public key */ | ||
1825 | Key * | 193 | Key * |
1826 | key_demote(const Key *k) | 194 | key_demote(const Key *k) |
1827 | { | 195 | { |
1828 | Key *pk; | 196 | int r; |
1829 | 197 | Key *ret = NULL; | |
1830 | pk = xcalloc(1, sizeof(*pk)); | ||
1831 | pk->type = k->type; | ||
1832 | pk->flags = k->flags; | ||
1833 | pk->ecdsa_nid = k->ecdsa_nid; | ||
1834 | pk->dsa = NULL; | ||
1835 | pk->ecdsa = NULL; | ||
1836 | pk->rsa = NULL; | ||
1837 | pk->ed25519_pk = NULL; | ||
1838 | pk->ed25519_sk = NULL; | ||
1839 | |||
1840 | switch (k->type) { | ||
1841 | case KEY_RSA_CERT_V00: | ||
1842 | case KEY_RSA_CERT: | ||
1843 | key_cert_copy(k, pk); | ||
1844 | /* FALLTHROUGH */ | ||
1845 | case KEY_RSA1: | ||
1846 | case KEY_RSA: | ||
1847 | if ((pk->rsa = RSA_new()) == NULL) | ||
1848 | fatal("key_demote: RSA_new failed"); | ||
1849 | if ((pk->rsa->e = BN_dup(k->rsa->e)) == NULL) | ||
1850 | fatal("key_demote: BN_dup failed"); | ||
1851 | if ((pk->rsa->n = BN_dup(k->rsa->n)) == NULL) | ||
1852 | fatal("key_demote: BN_dup failed"); | ||
1853 | break; | ||
1854 | case KEY_DSA_CERT_V00: | ||
1855 | case KEY_DSA_CERT: | ||
1856 | key_cert_copy(k, pk); | ||
1857 | /* FALLTHROUGH */ | ||
1858 | case KEY_DSA: | ||
1859 | if ((pk->dsa = DSA_new()) == NULL) | ||
1860 | fatal("key_demote: DSA_new failed"); | ||
1861 | if ((pk->dsa->p = BN_dup(k->dsa->p)) == NULL) | ||
1862 | fatal("key_demote: BN_dup failed"); | ||
1863 | if ((pk->dsa->q = BN_dup(k->dsa->q)) == NULL) | ||
1864 | fatal("key_demote: BN_dup failed"); | ||
1865 | if ((pk->dsa->g = BN_dup(k->dsa->g)) == NULL) | ||
1866 | fatal("key_demote: BN_dup failed"); | ||
1867 | if ((pk->dsa->pub_key = BN_dup(k->dsa->pub_key)) == NULL) | ||
1868 | fatal("key_demote: BN_dup failed"); | ||
1869 | break; | ||
1870 | #ifdef OPENSSL_HAS_ECC | ||
1871 | case KEY_ECDSA_CERT: | ||
1872 | key_cert_copy(k, pk); | ||
1873 | /* FALLTHROUGH */ | ||
1874 | case KEY_ECDSA: | ||
1875 | if ((pk->ecdsa = EC_KEY_new_by_curve_name(pk->ecdsa_nid)) == NULL) | ||
1876 | fatal("key_demote: EC_KEY_new_by_curve_name failed"); | ||
1877 | if (EC_KEY_set_public_key(pk->ecdsa, | ||
1878 | EC_KEY_get0_public_key(k->ecdsa)) != 1) | ||
1879 | fatal("key_demote: EC_KEY_set_public_key failed"); | ||
1880 | break; | ||
1881 | #endif | ||
1882 | case KEY_ED25519_CERT: | ||
1883 | key_cert_copy(k, pk); | ||
1884 | /* FALLTHROUGH */ | ||
1885 | case KEY_ED25519: | ||
1886 | if (k->ed25519_pk != NULL) { | ||
1887 | pk->ed25519_pk = xmalloc(ED25519_PK_SZ); | ||
1888 | memcpy(pk->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ); | ||
1889 | } | ||
1890 | break; | ||
1891 | default: | ||
1892 | fatal("key_demote: bad key type %d", k->type); | ||
1893 | break; | ||
1894 | } | ||
1895 | |||
1896 | return (pk); | ||
1897 | } | ||
1898 | 198 | ||
1899 | int | 199 | if ((r = sshkey_demote(k, &ret)) != 0) |
1900 | key_is_cert(const Key *k) | 200 | fatal("%s: %s", __func__, ssh_err(r)); |
1901 | { | 201 | return ret; |
1902 | if (k == NULL) | ||
1903 | return 0; | ||
1904 | return key_type_is_cert(k->type); | ||
1905 | } | ||
1906 | |||
1907 | /* Return the cert-less equivalent to a certified key type */ | ||
1908 | int | ||
1909 | key_type_plain(int type) | ||
1910 | { | ||
1911 | switch (type) { | ||
1912 | case KEY_RSA_CERT_V00: | ||
1913 | case KEY_RSA_CERT: | ||
1914 | return KEY_RSA; | ||
1915 | case KEY_DSA_CERT_V00: | ||
1916 | case KEY_DSA_CERT: | ||
1917 | return KEY_DSA; | ||
1918 | case KEY_ECDSA_CERT: | ||
1919 | return KEY_ECDSA; | ||
1920 | case KEY_ED25519_CERT: | ||
1921 | return KEY_ED25519; | ||
1922 | default: | ||
1923 | return type; | ||
1924 | } | ||
1925 | } | 202 | } |
1926 | 203 | ||
1927 | /* Convert a plain key to their _CERT equivalent */ | ||
1928 | int | 204 | int |
1929 | key_to_certified(Key *k, int legacy) | 205 | key_to_certified(Key *k, int legacy) |
1930 | { | 206 | { |
1931 | switch (k->type) { | 207 | int r; |
1932 | case KEY_RSA: | 208 | |
1933 | k->cert = cert_new(); | 209 | if ((r = sshkey_to_certified(k, legacy)) != 0) { |
1934 | k->type = legacy ? KEY_RSA_CERT_V00 : KEY_RSA_CERT; | 210 | fatal_on_fatal_errors(r, __func__, 0); |
1935 | return 0; | 211 | error("%s: %s", __func__, ssh_err(r)); |
1936 | case KEY_DSA: | ||
1937 | k->cert = cert_new(); | ||
1938 | k->type = legacy ? KEY_DSA_CERT_V00 : KEY_DSA_CERT; | ||
1939 | return 0; | ||
1940 | case KEY_ECDSA: | ||
1941 | if (legacy) | ||
1942 | fatal("%s: legacy ECDSA certificates are not supported", | ||
1943 | __func__); | ||
1944 | k->cert = cert_new(); | ||
1945 | k->type = KEY_ECDSA_CERT; | ||
1946 | return 0; | ||
1947 | case KEY_ED25519: | ||
1948 | if (legacy) | ||
1949 | fatal("%s: legacy ED25519 certificates are not " | ||
1950 | "supported", __func__); | ||
1951 | k->cert = cert_new(); | ||
1952 | k->type = KEY_ED25519_CERT; | ||
1953 | return 0; | ||
1954 | default: | ||
1955 | error("%s: key has incorrect type %s", __func__, key_type(k)); | ||
1956 | return -1; | 212 | return -1; |
1957 | } | 213 | } |
214 | return 0; | ||
1958 | } | 215 | } |
1959 | 216 | ||
1960 | /* Convert a certificate to its raw key equivalent */ | ||
1961 | int | 217 | int |
1962 | key_drop_cert(Key *k) | 218 | key_drop_cert(Key *k) |
1963 | { | 219 | { |
1964 | if (!key_type_is_cert(k->type)) { | 220 | int r; |
1965 | error("%s: key has incorrect type %s", __func__, key_type(k)); | 221 | |
222 | if ((r = sshkey_drop_cert(k)) != 0) { | ||
223 | fatal_on_fatal_errors(r, __func__, 0); | ||
224 | error("%s: %s", __func__, ssh_err(r)); | ||
1966 | return -1; | 225 | return -1; |
1967 | } | 226 | } |
1968 | cert_free(k->cert); | ||
1969 | k->cert = NULL; | ||
1970 | k->type = key_type_plain(k->type); | ||
1971 | return 0; | 227 | return 0; |
1972 | } | 228 | } |
1973 | 229 | ||
1974 | /* Sign a certified key, (re-)generating the signed certblob. */ | ||
1975 | int | 230 | int |
1976 | key_certify(Key *k, Key *ca) | 231 | key_certify(Key *k, Key *ca) |
1977 | { | 232 | { |
1978 | Buffer principals; | 233 | int r; |
1979 | u_char *ca_blob, *sig_blob, nonce[32]; | ||
1980 | u_int i, ca_len, sig_len; | ||
1981 | |||
1982 | if (k->cert == NULL) { | ||
1983 | error("%s: key lacks cert info", __func__); | ||
1984 | return -1; | ||
1985 | } | ||
1986 | |||
1987 | if (!key_is_cert(k)) { | ||
1988 | error("%s: certificate has unknown type %d", __func__, | ||
1989 | k->cert->type); | ||
1990 | return -1; | ||
1991 | } | ||
1992 | |||
1993 | if (!key_type_is_valid_ca(ca->type)) { | ||
1994 | error("%s: CA key has unsupported type %s", __func__, | ||
1995 | key_type(ca)); | ||
1996 | return -1; | ||
1997 | } | ||
1998 | |||
1999 | key_to_blob(ca, &ca_blob, &ca_len); | ||
2000 | |||
2001 | buffer_clear(&k->cert->certblob); | ||
2002 | buffer_put_cstring(&k->cert->certblob, key_ssh_name(k)); | ||
2003 | |||
2004 | /* -v01 certs put nonce first */ | ||
2005 | arc4random_buf(&nonce, sizeof(nonce)); | ||
2006 | if (!key_cert_is_legacy(k)) | ||
2007 | buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce)); | ||
2008 | |||
2009 | /* XXX this substantially duplicates to_blob(); refactor */ | ||
2010 | switch (k->type) { | ||
2011 | case KEY_DSA_CERT_V00: | ||
2012 | case KEY_DSA_CERT: | ||
2013 | buffer_put_bignum2(&k->cert->certblob, k->dsa->p); | ||
2014 | buffer_put_bignum2(&k->cert->certblob, k->dsa->q); | ||
2015 | buffer_put_bignum2(&k->cert->certblob, k->dsa->g); | ||
2016 | buffer_put_bignum2(&k->cert->certblob, k->dsa->pub_key); | ||
2017 | break; | ||
2018 | #ifdef OPENSSL_HAS_ECC | ||
2019 | case KEY_ECDSA_CERT: | ||
2020 | buffer_put_cstring(&k->cert->certblob, | ||
2021 | key_curve_nid_to_name(k->ecdsa_nid)); | ||
2022 | buffer_put_ecpoint(&k->cert->certblob, | ||
2023 | EC_KEY_get0_group(k->ecdsa), | ||
2024 | EC_KEY_get0_public_key(k->ecdsa)); | ||
2025 | break; | ||
2026 | #endif | ||
2027 | case KEY_RSA_CERT_V00: | ||
2028 | case KEY_RSA_CERT: | ||
2029 | buffer_put_bignum2(&k->cert->certblob, k->rsa->e); | ||
2030 | buffer_put_bignum2(&k->cert->certblob, k->rsa->n); | ||
2031 | break; | ||
2032 | case KEY_ED25519_CERT: | ||
2033 | buffer_put_string(&k->cert->certblob, | ||
2034 | k->ed25519_pk, ED25519_PK_SZ); | ||
2035 | break; | ||
2036 | default: | ||
2037 | error("%s: key has incorrect type %s", __func__, key_type(k)); | ||
2038 | buffer_clear(&k->cert->certblob); | ||
2039 | free(ca_blob); | ||
2040 | return -1; | ||
2041 | } | ||
2042 | |||
2043 | /* -v01 certs have a serial number next */ | ||
2044 | if (!key_cert_is_legacy(k)) | ||
2045 | buffer_put_int64(&k->cert->certblob, k->cert->serial); | ||
2046 | |||
2047 | buffer_put_int(&k->cert->certblob, k->cert->type); | ||
2048 | buffer_put_cstring(&k->cert->certblob, k->cert->key_id); | ||
2049 | |||
2050 | buffer_init(&principals); | ||
2051 | for (i = 0; i < k->cert->nprincipals; i++) | ||
2052 | buffer_put_cstring(&principals, k->cert->principals[i]); | ||
2053 | buffer_put_string(&k->cert->certblob, buffer_ptr(&principals), | ||
2054 | buffer_len(&principals)); | ||
2055 | buffer_free(&principals); | ||
2056 | |||
2057 | buffer_put_int64(&k->cert->certblob, k->cert->valid_after); | ||
2058 | buffer_put_int64(&k->cert->certblob, k->cert->valid_before); | ||
2059 | buffer_put_string(&k->cert->certblob, | ||
2060 | buffer_ptr(&k->cert->critical), buffer_len(&k->cert->critical)); | ||
2061 | |||
2062 | /* -v01 certs have non-critical options here */ | ||
2063 | if (!key_cert_is_legacy(k)) { | ||
2064 | buffer_put_string(&k->cert->certblob, | ||
2065 | buffer_ptr(&k->cert->extensions), | ||
2066 | buffer_len(&k->cert->extensions)); | ||
2067 | } | ||
2068 | |||
2069 | /* -v00 certs put the nonce at the end */ | ||
2070 | if (key_cert_is_legacy(k)) | ||
2071 | buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce)); | ||
2072 | |||
2073 | buffer_put_string(&k->cert->certblob, NULL, 0); /* reserved */ | ||
2074 | buffer_put_string(&k->cert->certblob, ca_blob, ca_len); | ||
2075 | free(ca_blob); | ||
2076 | 234 | ||
2077 | /* Sign the whole mess */ | 235 | if ((r = sshkey_certify(k, ca)) != 0) { |
2078 | if (key_sign(ca, &sig_blob, &sig_len, buffer_ptr(&k->cert->certblob), | 236 | fatal_on_fatal_errors(r, __func__, 0); |
2079 | buffer_len(&k->cert->certblob)) != 0) { | 237 | error("%s: %s", __func__, ssh_err(r)); |
2080 | error("%s: signature operation failed", __func__); | ||
2081 | buffer_clear(&k->cert->certblob); | ||
2082 | return -1; | 238 | return -1; |
2083 | } | 239 | } |
2084 | /* Append signature and we are done */ | ||
2085 | buffer_put_string(&k->cert->certblob, sig_blob, sig_len); | ||
2086 | free(sig_blob); | ||
2087 | |||
2088 | return 0; | 240 | return 0; |
2089 | } | 241 | } |
2090 | 242 | ||
@@ -2092,535 +244,236 @@ int | |||
2092 | key_cert_check_authority(const Key *k, int want_host, int require_principal, | 244 | key_cert_check_authority(const Key *k, int want_host, int require_principal, |
2093 | const char *name, const char **reason) | 245 | const char *name, const char **reason) |
2094 | { | 246 | { |
2095 | u_int i, principal_matches; | 247 | int r; |
2096 | time_t now = time(NULL); | 248 | |
2097 | 249 | if ((r = sshkey_cert_check_authority(k, want_host, require_principal, | |
2098 | if (want_host) { | 250 | name, reason)) != 0) { |
2099 | if (k->cert->type != SSH2_CERT_TYPE_HOST) { | 251 | fatal_on_fatal_errors(r, __func__, 0); |
2100 | *reason = "Certificate invalid: not a host certificate"; | 252 | error("%s: %s", __func__, ssh_err(r)); |
2101 | return -1; | ||
2102 | } | ||
2103 | } else { | ||
2104 | if (k->cert->type != SSH2_CERT_TYPE_USER) { | ||
2105 | *reason = "Certificate invalid: not a user certificate"; | ||
2106 | return -1; | ||
2107 | } | ||
2108 | } | ||
2109 | if (now < 0) { | ||
2110 | error("%s: system clock lies before epoch", __func__); | ||
2111 | *reason = "Certificate invalid: not yet valid"; | ||
2112 | return -1; | ||
2113 | } | ||
2114 | if ((u_int64_t)now < k->cert->valid_after) { | ||
2115 | *reason = "Certificate invalid: not yet valid"; | ||
2116 | return -1; | ||
2117 | } | ||
2118 | if ((u_int64_t)now >= k->cert->valid_before) { | ||
2119 | *reason = "Certificate invalid: expired"; | ||
2120 | return -1; | 253 | return -1; |
2121 | } | 254 | } |
2122 | if (k->cert->nprincipals == 0) { | ||
2123 | if (require_principal) { | ||
2124 | *reason = "Certificate lacks principal list"; | ||
2125 | return -1; | ||
2126 | } | ||
2127 | } else if (name != NULL) { | ||
2128 | principal_matches = 0; | ||
2129 | for (i = 0; i < k->cert->nprincipals; i++) { | ||
2130 | if (strcmp(name, k->cert->principals[i]) == 0) { | ||
2131 | principal_matches = 1; | ||
2132 | break; | ||
2133 | } | ||
2134 | } | ||
2135 | if (!principal_matches) { | ||
2136 | *reason = "Certificate invalid: name is not a listed " | ||
2137 | "principal"; | ||
2138 | return -1; | ||
2139 | } | ||
2140 | } | ||
2141 | return 0; | 255 | return 0; |
2142 | } | 256 | } |
2143 | 257 | ||
258 | #if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) | ||
2144 | int | 259 | int |
2145 | key_cert_is_legacy(const Key *k) | 260 | key_ec_validate_public(const EC_GROUP *group, const EC_POINT *public) |
2146 | { | 261 | { |
2147 | switch (k->type) { | 262 | int r; |
2148 | case KEY_DSA_CERT_V00: | 263 | |
2149 | case KEY_RSA_CERT_V00: | 264 | if ((r = sshkey_ec_validate_public(group, public)) != 0) { |
2150 | return 1; | 265 | fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); |
2151 | default: | 266 | error("%s: %s", __func__, ssh_err(r)); |
2152 | return 0; | 267 | return -1; |
2153 | } | 268 | } |
269 | return 0; | ||
2154 | } | 270 | } |
2155 | 271 | ||
2156 | /* XXX: these are really begging for a table-driven approach */ | ||
2157 | int | 272 | int |
2158 | key_curve_name_to_nid(const char *name) | 273 | key_ec_validate_private(const EC_KEY *key) |
2159 | { | 274 | { |
2160 | #ifdef OPENSSL_HAS_ECC | 275 | int r; |
2161 | if (strcmp(name, "nistp256") == 0) | 276 | |
2162 | return NID_X9_62_prime256v1; | 277 | if ((r = sshkey_ec_validate_private(key)) != 0) { |
2163 | else if (strcmp(name, "nistp384") == 0) | 278 | fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); |
2164 | return NID_secp384r1; | 279 | error("%s: %s", __func__, ssh_err(r)); |
2165 | # ifdef OPENSSL_HAS_NISTP521 | 280 | return -1; |
2166 | else if (strcmp(name, "nistp521") == 0) | 281 | } |
2167 | return NID_secp521r1; | 282 | return 0; |
2168 | # endif | ||
2169 | #endif | ||
2170 | |||
2171 | debug("%s: unsupported EC curve name \"%.100s\"", __func__, name); | ||
2172 | return -1; | ||
2173 | } | 283 | } |
284 | #endif /* WITH_OPENSSL */ | ||
2174 | 285 | ||
2175 | u_int | 286 | void |
2176 | key_curve_nid_to_bits(int nid) | 287 | key_private_serialize(const Key *key, struct sshbuf *b) |
2177 | { | 288 | { |
2178 | switch (nid) { | 289 | int r; |
2179 | #ifdef OPENSSL_HAS_ECC | 290 | |
2180 | case NID_X9_62_prime256v1: | 291 | if ((r = sshkey_private_serialize(key, b)) != 0) |
2181 | return 256; | 292 | fatal("%s: %s", __func__, ssh_err(r)); |
2182 | case NID_secp384r1: | ||
2183 | return 384; | ||
2184 | # ifdef OPENSSL_HAS_NISTP521 | ||
2185 | case NID_secp521r1: | ||
2186 | return 521; | ||
2187 | # endif | ||
2188 | #endif | ||
2189 | default: | ||
2190 | error("%s: unsupported EC curve nid %d", __func__, nid); | ||
2191 | return 0; | ||
2192 | } | ||
2193 | } | 293 | } |
2194 | 294 | ||
2195 | const char * | 295 | Key * |
2196 | key_curve_nid_to_name(int nid) | 296 | key_private_deserialize(struct sshbuf *blob) |
2197 | { | 297 | { |
2198 | #ifdef OPENSSL_HAS_ECC | 298 | int r; |
2199 | if (nid == NID_X9_62_prime256v1) | 299 | Key *ret = NULL; |
2200 | return "nistp256"; | 300 | |
2201 | else if (nid == NID_secp384r1) | 301 | if ((r = sshkey_private_deserialize(blob, &ret)) != 0) { |
2202 | return "nistp384"; | 302 | fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); |
2203 | # ifdef OPENSSL_HAS_NISTP521 | 303 | error("%s: %s", __func__, ssh_err(r)); |
2204 | else if (nid == NID_secp521r1) | 304 | return NULL; |
2205 | return "nistp521"; | 305 | } |
2206 | # endif | 306 | return ret; |
2207 | #endif | ||
2208 | error("%s: unsupported EC curve nid %d", __func__, nid); | ||
2209 | return NULL; | ||
2210 | } | 307 | } |
2211 | 308 | ||
2212 | #ifdef OPENSSL_HAS_ECC | 309 | /* authfile.c */ |
310 | |||
2213 | int | 311 | int |
2214 | key_ec_nid_to_hash_alg(int nid) | 312 | key_save_private(Key *key, const char *filename, const char *passphrase, |
313 | const char *comment, int force_new_format, const char *new_format_cipher, | ||
314 | int new_format_rounds) | ||
2215 | { | 315 | { |
2216 | int kbits = key_curve_nid_to_bits(nid); | 316 | int r; |
2217 | 317 | ||
2218 | if (kbits == 0) | 318 | if ((r = sshkey_save_private(key, filename, passphrase, comment, |
2219 | fatal("%s: invalid nid %d", __func__, nid); | 319 | force_new_format, new_format_cipher, new_format_rounds)) != 0) { |
2220 | /* RFC5656 section 6.2.1 */ | 320 | fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); |
2221 | if (kbits <= 256) | 321 | error("%s: %s", __func__, ssh_err(r)); |
2222 | return SSH_DIGEST_SHA256; | 322 | return 0; |
2223 | else if (kbits <= 384) | 323 | } |
2224 | return SSH_DIGEST_SHA384; | 324 | return 1; |
2225 | else | ||
2226 | return SSH_DIGEST_SHA512; | ||
2227 | } | 325 | } |
2228 | 326 | ||
2229 | int | 327 | int |
2230 | key_ec_validate_public(const EC_GROUP *group, const EC_POINT *public) | 328 | key_load_file(int fd, const char *filename, struct sshbuf *blob) |
2231 | { | 329 | { |
2232 | BN_CTX *bnctx; | 330 | int r; |
2233 | EC_POINT *nq = NULL; | ||
2234 | BIGNUM *order, *x, *y, *tmp; | ||
2235 | int ret = -1; | ||
2236 | |||
2237 | if ((bnctx = BN_CTX_new()) == NULL) | ||
2238 | fatal("%s: BN_CTX_new failed", __func__); | ||
2239 | BN_CTX_start(bnctx); | ||
2240 | |||
2241 | /* | ||
2242 | * We shouldn't ever hit this case because bignum_get_ecpoint() | ||
2243 | * refuses to load GF2m points. | ||
2244 | */ | ||
2245 | if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != | ||
2246 | NID_X9_62_prime_field) { | ||
2247 | error("%s: group is not a prime field", __func__); | ||
2248 | goto out; | ||
2249 | } | ||
2250 | 331 | ||
2251 | /* Q != infinity */ | 332 | if ((r = sshkey_load_file(fd, filename, blob)) != 0) { |
2252 | if (EC_POINT_is_at_infinity(group, public)) { | 333 | fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); |
2253 | error("%s: received degenerate public key (infinity)", | 334 | error("%s: %s", __func__, ssh_err(r)); |
2254 | __func__); | 335 | return 0; |
2255 | goto out; | ||
2256 | } | 336 | } |
337 | return 1; | ||
338 | } | ||
2257 | 339 | ||
2258 | if ((x = BN_CTX_get(bnctx)) == NULL || | 340 | Key * |
2259 | (y = BN_CTX_get(bnctx)) == NULL || | 341 | key_load_cert(const char *filename) |
2260 | (order = BN_CTX_get(bnctx)) == NULL || | 342 | { |
2261 | (tmp = BN_CTX_get(bnctx)) == NULL) | 343 | int r; |
2262 | fatal("%s: BN_CTX_get failed", __func__); | 344 | Key *ret = NULL; |
2263 | 345 | ||
2264 | /* log2(x) > log2(order)/2, log2(y) > log2(order)/2 */ | 346 | if ((r = sshkey_load_cert(filename, &ret)) != 0) { |
2265 | if (EC_GROUP_get_order(group, order, bnctx) != 1) | 347 | fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); |
2266 | fatal("%s: EC_GROUP_get_order failed", __func__); | 348 | /* Old authfile.c ignored all file errors. */ |
2267 | if (EC_POINT_get_affine_coordinates_GFp(group, public, | 349 | if (r == SSH_ERR_SYSTEM_ERROR) |
2268 | x, y, bnctx) != 1) | 350 | debug("%s: %s", __func__, ssh_err(r)); |
2269 | fatal("%s: EC_POINT_get_affine_coordinates_GFp", __func__); | 351 | else |
2270 | if (BN_num_bits(x) <= BN_num_bits(order) / 2) { | 352 | error("%s: %s", __func__, ssh_err(r)); |
2271 | error("%s: public key x coordinate too small: " | 353 | return NULL; |
2272 | "bits(x) = %d, bits(order)/2 = %d", __func__, | ||
2273 | BN_num_bits(x), BN_num_bits(order) / 2); | ||
2274 | goto out; | ||
2275 | } | ||
2276 | if (BN_num_bits(y) <= BN_num_bits(order) / 2) { | ||
2277 | error("%s: public key y coordinate too small: " | ||
2278 | "bits(y) = %d, bits(order)/2 = %d", __func__, | ||
2279 | BN_num_bits(x), BN_num_bits(order) / 2); | ||
2280 | goto out; | ||
2281 | } | 354 | } |
355 | return ret; | ||
2282 | 356 | ||
2283 | /* nQ == infinity (n == order of subgroup) */ | 357 | } |
2284 | if ((nq = EC_POINT_new(group)) == NULL) | ||
2285 | fatal("%s: BN_CTX_tmp failed", __func__); | ||
2286 | if (EC_POINT_mul(group, nq, NULL, public, order, bnctx) != 1) | ||
2287 | fatal("%s: EC_GROUP_mul failed", __func__); | ||
2288 | if (EC_POINT_is_at_infinity(group, nq) != 1) { | ||
2289 | error("%s: received degenerate public key (nQ != infinity)", | ||
2290 | __func__); | ||
2291 | goto out; | ||
2292 | } | ||
2293 | 358 | ||
2294 | /* x < order - 1, y < order - 1 */ | 359 | Key * |
2295 | if (!BN_sub(tmp, order, BN_value_one())) | 360 | key_load_public(const char *filename, char **commentp) |
2296 | fatal("%s: BN_sub failed", __func__); | 361 | { |
2297 | if (BN_cmp(x, tmp) >= 0) { | 362 | int r; |
2298 | error("%s: public key x coordinate >= group order - 1", | 363 | Key *ret = NULL; |
2299 | __func__); | 364 | |
2300 | goto out; | 365 | if ((r = sshkey_load_public(filename, &ret, commentp)) != 0) { |
2301 | } | 366 | fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); |
2302 | if (BN_cmp(y, tmp) >= 0) { | 367 | /* Old authfile.c ignored all file errors. */ |
2303 | error("%s: public key y coordinate >= group order - 1", | 368 | if (r == SSH_ERR_SYSTEM_ERROR) |
2304 | __func__); | 369 | debug("%s: %s", __func__, ssh_err(r)); |
2305 | goto out; | 370 | else |
371 | error("%s: %s", __func__, ssh_err(r)); | ||
372 | return NULL; | ||
2306 | } | 373 | } |
2307 | ret = 0; | ||
2308 | out: | ||
2309 | BN_CTX_free(bnctx); | ||
2310 | EC_POINT_free(nq); | ||
2311 | return ret; | 374 | return ret; |
2312 | } | 375 | } |
2313 | 376 | ||
2314 | int | 377 | Key * |
2315 | key_ec_validate_private(const EC_KEY *key) | 378 | key_load_private(const char *path, const char *passphrase, |
2316 | { | 379 | char **commentp) |
2317 | BN_CTX *bnctx; | 380 | { |
2318 | BIGNUM *order, *tmp; | 381 | int r; |
2319 | int ret = -1; | 382 | Key *ret = NULL; |
2320 | 383 | ||
2321 | if ((bnctx = BN_CTX_new()) == NULL) | 384 | if ((r = sshkey_load_private(path, passphrase, &ret, commentp)) != 0) { |
2322 | fatal("%s: BN_CTX_new failed", __func__); | 385 | fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); |
2323 | BN_CTX_start(bnctx); | 386 | /* Old authfile.c ignored all file errors. */ |
2324 | 387 | if (r == SSH_ERR_SYSTEM_ERROR || | |
2325 | if ((order = BN_CTX_get(bnctx)) == NULL || | 388 | r == SSH_ERR_KEY_WRONG_PASSPHRASE) |
2326 | (tmp = BN_CTX_get(bnctx)) == NULL) | 389 | debug("%s: %s", __func__, ssh_err(r)); |
2327 | fatal("%s: BN_CTX_get failed", __func__); | 390 | else |
2328 | 391 | error("%s: %s", __func__, ssh_err(r)); | |
2329 | /* log2(private) > log2(order)/2 */ | 392 | return NULL; |
2330 | if (EC_GROUP_get_order(EC_KEY_get0_group(key), order, bnctx) != 1) | ||
2331 | fatal("%s: EC_GROUP_get_order failed", __func__); | ||
2332 | if (BN_num_bits(EC_KEY_get0_private_key(key)) <= | ||
2333 | BN_num_bits(order) / 2) { | ||
2334 | error("%s: private key too small: " | ||
2335 | "bits(y) = %d, bits(order)/2 = %d", __func__, | ||
2336 | BN_num_bits(EC_KEY_get0_private_key(key)), | ||
2337 | BN_num_bits(order) / 2); | ||
2338 | goto out; | ||
2339 | } | 393 | } |
394 | return ret; | ||
395 | } | ||
2340 | 396 | ||
2341 | /* private < order - 1 */ | 397 | Key * |
2342 | if (!BN_sub(tmp, order, BN_value_one())) | 398 | key_load_private_cert(int type, const char *filename, const char *passphrase, |
2343 | fatal("%s: BN_sub failed", __func__); | 399 | int *perm_ok) |
2344 | if (BN_cmp(EC_KEY_get0_private_key(key), tmp) >= 0) { | 400 | { |
2345 | error("%s: private key >= group order - 1", __func__); | 401 | int r; |
2346 | goto out; | 402 | Key *ret = NULL; |
403 | |||
404 | if ((r = sshkey_load_private_cert(type, filename, passphrase, | ||
405 | &ret, perm_ok)) != 0) { | ||
406 | fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); | ||
407 | /* Old authfile.c ignored all file errors. */ | ||
408 | if (r == SSH_ERR_SYSTEM_ERROR || | ||
409 | r == SSH_ERR_KEY_WRONG_PASSPHRASE) | ||
410 | debug("%s: %s", __func__, ssh_err(r)); | ||
411 | else | ||
412 | error("%s: %s", __func__, ssh_err(r)); | ||
413 | return NULL; | ||
2347 | } | 414 | } |
2348 | ret = 0; | ||
2349 | out: | ||
2350 | BN_CTX_free(bnctx); | ||
2351 | return ret; | 415 | return ret; |
2352 | } | 416 | } |
2353 | 417 | ||
2354 | #if defined(DEBUG_KEXECDH) || defined(DEBUG_PK) | 418 | Key * |
2355 | void | 419 | key_load_private_type(int type, const char *filename, const char *passphrase, |
2356 | key_dump_ec_point(const EC_GROUP *group, const EC_POINT *point) | 420 | char **commentp, int *perm_ok) |
2357 | { | 421 | { |
2358 | BIGNUM *x, *y; | 422 | int r; |
2359 | BN_CTX *bnctx; | 423 | Key *ret = NULL; |
2360 | 424 | ||
2361 | if (point == NULL) { | 425 | if ((r = sshkey_load_private_type(type, filename, passphrase, |
2362 | fputs("point=(NULL)\n", stderr); | 426 | &ret, commentp, perm_ok)) != 0) { |
2363 | return; | 427 | fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); |
428 | /* Old authfile.c ignored all file errors. */ | ||
429 | if (r == SSH_ERR_SYSTEM_ERROR || | ||
430 | (r == SSH_ERR_KEY_WRONG_PASSPHRASE)) | ||
431 | debug("%s: %s", __func__, ssh_err(r)); | ||
432 | else | ||
433 | error("%s: %s", __func__, ssh_err(r)); | ||
434 | return NULL; | ||
2364 | } | 435 | } |
2365 | if ((bnctx = BN_CTX_new()) == NULL) | 436 | return ret; |
2366 | fatal("%s: BN_CTX_new failed", __func__); | ||
2367 | BN_CTX_start(bnctx); | ||
2368 | if ((x = BN_CTX_get(bnctx)) == NULL || (y = BN_CTX_get(bnctx)) == NULL) | ||
2369 | fatal("%s: BN_CTX_get failed", __func__); | ||
2370 | if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != | ||
2371 | NID_X9_62_prime_field) | ||
2372 | fatal("%s: group is not a prime field", __func__); | ||
2373 | if (EC_POINT_get_affine_coordinates_GFp(group, point, x, y, bnctx) != 1) | ||
2374 | fatal("%s: EC_POINT_get_affine_coordinates_GFp", __func__); | ||
2375 | fputs("x=", stderr); | ||
2376 | BN_print_fp(stderr, x); | ||
2377 | fputs("\ny=", stderr); | ||
2378 | BN_print_fp(stderr, y); | ||
2379 | fputs("\n", stderr); | ||
2380 | BN_CTX_free(bnctx); | ||
2381 | } | 437 | } |
2382 | 438 | ||
2383 | void | 439 | #ifdef WITH_OPENSSL |
2384 | key_dump_ec_key(const EC_KEY *key) | 440 | Key * |
2385 | { | 441 | key_load_private_pem(int fd, int type, const char *passphrase, |
2386 | const BIGNUM *exponent; | 442 | char **commentp) |
2387 | 443 | { | |
2388 | key_dump_ec_point(EC_KEY_get0_group(key), EC_KEY_get0_public_key(key)); | 444 | int r; |
2389 | fputs("exponent=", stderr); | 445 | Key *ret = NULL; |
2390 | if ((exponent = EC_KEY_get0_private_key(key)) == NULL) | 446 | |
2391 | fputs("(NULL)", stderr); | 447 | if ((r = sshkey_load_private_pem(fd, type, passphrase, |
2392 | else | 448 | &ret, commentp)) != 0) { |
2393 | BN_print_fp(stderr, EC_KEY_get0_private_key(key)); | 449 | fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); |
2394 | fputs("\n", stderr); | 450 | if (r == SSH_ERR_KEY_WRONG_PASSPHRASE) |
451 | debug("%s: %s", __func__, ssh_err(r)); | ||
452 | else | ||
453 | error("%s: %s", __func__, ssh_err(r)); | ||
454 | return NULL; | ||
455 | } | ||
456 | return ret; | ||
2395 | } | 457 | } |
2396 | #endif /* defined(DEBUG_KEXECDH) || defined(DEBUG_PK) */ | 458 | #endif /* WITH_OPENSSL */ |
2397 | #endif /* OPENSSL_HAS_ECC */ | ||
2398 | 459 | ||
2399 | void | 460 | int |
2400 | key_private_serialize(const Key *key, Buffer *b) | 461 | key_perm_ok(int fd, const char *filename) |
2401 | { | 462 | { |
2402 | buffer_put_cstring(b, key_ssh_name(key)); | 463 | return sshkey_perm_ok(fd, filename) == 0 ? 1 : 0; |
2403 | switch (key->type) { | ||
2404 | case KEY_RSA: | ||
2405 | buffer_put_bignum2(b, key->rsa->n); | ||
2406 | buffer_put_bignum2(b, key->rsa->e); | ||
2407 | buffer_put_bignum2(b, key->rsa->d); | ||
2408 | buffer_put_bignum2(b, key->rsa->iqmp); | ||
2409 | buffer_put_bignum2(b, key->rsa->p); | ||
2410 | buffer_put_bignum2(b, key->rsa->q); | ||
2411 | break; | ||
2412 | case KEY_RSA_CERT_V00: | ||
2413 | case KEY_RSA_CERT: | ||
2414 | if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0) | ||
2415 | fatal("%s: no cert/certblob", __func__); | ||
2416 | buffer_put_string(b, buffer_ptr(&key->cert->certblob), | ||
2417 | buffer_len(&key->cert->certblob)); | ||
2418 | buffer_put_bignum2(b, key->rsa->d); | ||
2419 | buffer_put_bignum2(b, key->rsa->iqmp); | ||
2420 | buffer_put_bignum2(b, key->rsa->p); | ||
2421 | buffer_put_bignum2(b, key->rsa->q); | ||
2422 | break; | ||
2423 | case KEY_DSA: | ||
2424 | buffer_put_bignum2(b, key->dsa->p); | ||
2425 | buffer_put_bignum2(b, key->dsa->q); | ||
2426 | buffer_put_bignum2(b, key->dsa->g); | ||
2427 | buffer_put_bignum2(b, key->dsa->pub_key); | ||
2428 | buffer_put_bignum2(b, key->dsa->priv_key); | ||
2429 | break; | ||
2430 | case KEY_DSA_CERT_V00: | ||
2431 | case KEY_DSA_CERT: | ||
2432 | if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0) | ||
2433 | fatal("%s: no cert/certblob", __func__); | ||
2434 | buffer_put_string(b, buffer_ptr(&key->cert->certblob), | ||
2435 | buffer_len(&key->cert->certblob)); | ||
2436 | buffer_put_bignum2(b, key->dsa->priv_key); | ||
2437 | break; | ||
2438 | #ifdef OPENSSL_HAS_ECC | ||
2439 | case KEY_ECDSA: | ||
2440 | buffer_put_cstring(b, key_curve_nid_to_name(key->ecdsa_nid)); | ||
2441 | buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa), | ||
2442 | EC_KEY_get0_public_key(key->ecdsa)); | ||
2443 | buffer_put_bignum2(b, EC_KEY_get0_private_key(key->ecdsa)); | ||
2444 | break; | ||
2445 | case KEY_ECDSA_CERT: | ||
2446 | if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0) | ||
2447 | fatal("%s: no cert/certblob", __func__); | ||
2448 | buffer_put_string(b, buffer_ptr(&key->cert->certblob), | ||
2449 | buffer_len(&key->cert->certblob)); | ||
2450 | buffer_put_bignum2(b, EC_KEY_get0_private_key(key->ecdsa)); | ||
2451 | break; | ||
2452 | #endif /* OPENSSL_HAS_ECC */ | ||
2453 | case KEY_ED25519: | ||
2454 | buffer_put_string(b, key->ed25519_pk, ED25519_PK_SZ); | ||
2455 | buffer_put_string(b, key->ed25519_sk, ED25519_SK_SZ); | ||
2456 | break; | ||
2457 | case KEY_ED25519_CERT: | ||
2458 | if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0) | ||
2459 | fatal("%s: no cert/certblob", __func__); | ||
2460 | buffer_put_string(b, buffer_ptr(&key->cert->certblob), | ||
2461 | buffer_len(&key->cert->certblob)); | ||
2462 | buffer_put_string(b, key->ed25519_pk, ED25519_PK_SZ); | ||
2463 | buffer_put_string(b, key->ed25519_sk, ED25519_SK_SZ); | ||
2464 | break; | ||
2465 | } | ||
2466 | } | 464 | } |
2467 | 465 | ||
2468 | Key * | 466 | int |
2469 | key_private_deserialize(Buffer *blob) | 467 | key_in_file(Key *key, const char *filename, int strict_type) |
2470 | { | 468 | { |
2471 | char *type_name; | 469 | int r; |
2472 | Key *k = NULL; | 470 | |
2473 | u_char *cert; | 471 | if ((r = sshkey_in_file(key, filename, strict_type)) != 0) { |
2474 | u_int len, pklen, sklen; | 472 | fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); |
2475 | int type; | 473 | if (r == SSH_ERR_SYSTEM_ERROR && errno == ENOENT) |
2476 | #ifdef OPENSSL_HAS_ECC | 474 | return 0; |
2477 | char *curve; | 475 | error("%s: %s", __func__, ssh_err(r)); |
2478 | BIGNUM *exponent; | 476 | return r == SSH_ERR_KEY_NOT_FOUND ? 0 : -1; |
2479 | EC_POINT *q; | ||
2480 | #endif | ||
2481 | |||
2482 | type_name = buffer_get_string(blob, NULL); | ||
2483 | type = key_type_from_name(type_name); | ||
2484 | switch (type) { | ||
2485 | case KEY_DSA: | ||
2486 | k = key_new_private(type); | ||
2487 | buffer_get_bignum2(blob, k->dsa->p); | ||
2488 | buffer_get_bignum2(blob, k->dsa->q); | ||
2489 | buffer_get_bignum2(blob, k->dsa->g); | ||
2490 | buffer_get_bignum2(blob, k->dsa->pub_key); | ||
2491 | buffer_get_bignum2(blob, k->dsa->priv_key); | ||
2492 | break; | ||
2493 | case KEY_DSA_CERT_V00: | ||
2494 | case KEY_DSA_CERT: | ||
2495 | cert = buffer_get_string(blob, &len); | ||
2496 | if ((k = key_from_blob(cert, len)) == NULL) | ||
2497 | fatal("Certificate parse failed"); | ||
2498 | free(cert); | ||
2499 | key_add_private(k); | ||
2500 | buffer_get_bignum2(blob, k->dsa->priv_key); | ||
2501 | break; | ||
2502 | #ifdef OPENSSL_HAS_ECC | ||
2503 | case KEY_ECDSA: | ||
2504 | k = key_new_private(type); | ||
2505 | k->ecdsa_nid = key_ecdsa_nid_from_name(type_name); | ||
2506 | curve = buffer_get_string(blob, NULL); | ||
2507 | if (k->ecdsa_nid != key_curve_name_to_nid(curve)) | ||
2508 | fatal("%s: curve names mismatch", __func__); | ||
2509 | free(curve); | ||
2510 | k->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid); | ||
2511 | if (k->ecdsa == NULL) | ||
2512 | fatal("%s: EC_KEY_new_by_curve_name failed", | ||
2513 | __func__); | ||
2514 | q = EC_POINT_new(EC_KEY_get0_group(k->ecdsa)); | ||
2515 | if (q == NULL) | ||
2516 | fatal("%s: BN_new failed", __func__); | ||
2517 | if ((exponent = BN_new()) == NULL) | ||
2518 | fatal("%s: BN_new failed", __func__); | ||
2519 | buffer_get_ecpoint(blob, | ||
2520 | EC_KEY_get0_group(k->ecdsa), q); | ||
2521 | buffer_get_bignum2(blob, exponent); | ||
2522 | if (EC_KEY_set_public_key(k->ecdsa, q) != 1) | ||
2523 | fatal("%s: EC_KEY_set_public_key failed", | ||
2524 | __func__); | ||
2525 | if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) | ||
2526 | fatal("%s: EC_KEY_set_private_key failed", | ||
2527 | __func__); | ||
2528 | if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa), | ||
2529 | EC_KEY_get0_public_key(k->ecdsa)) != 0) | ||
2530 | fatal("%s: bad ECDSA public key", __func__); | ||
2531 | if (key_ec_validate_private(k->ecdsa) != 0) | ||
2532 | fatal("%s: bad ECDSA private key", __func__); | ||
2533 | BN_clear_free(exponent); | ||
2534 | EC_POINT_free(q); | ||
2535 | break; | ||
2536 | case KEY_ECDSA_CERT: | ||
2537 | cert = buffer_get_string(blob, &len); | ||
2538 | if ((k = key_from_blob(cert, len)) == NULL) | ||
2539 | fatal("Certificate parse failed"); | ||
2540 | free(cert); | ||
2541 | key_add_private(k); | ||
2542 | if ((exponent = BN_new()) == NULL) | ||
2543 | fatal("%s: BN_new failed", __func__); | ||
2544 | buffer_get_bignum2(blob, exponent); | ||
2545 | if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) | ||
2546 | fatal("%s: EC_KEY_set_private_key failed", | ||
2547 | __func__); | ||
2548 | if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa), | ||
2549 | EC_KEY_get0_public_key(k->ecdsa)) != 0 || | ||
2550 | key_ec_validate_private(k->ecdsa) != 0) | ||
2551 | fatal("%s: bad ECDSA key", __func__); | ||
2552 | BN_clear_free(exponent); | ||
2553 | break; | ||
2554 | #endif | ||
2555 | case KEY_RSA: | ||
2556 | k = key_new_private(type); | ||
2557 | buffer_get_bignum2(blob, k->rsa->n); | ||
2558 | buffer_get_bignum2(blob, k->rsa->e); | ||
2559 | buffer_get_bignum2(blob, k->rsa->d); | ||
2560 | buffer_get_bignum2(blob, k->rsa->iqmp); | ||
2561 | buffer_get_bignum2(blob, k->rsa->p); | ||
2562 | buffer_get_bignum2(blob, k->rsa->q); | ||
2563 | |||
2564 | /* Generate additional parameters */ | ||
2565 | rsa_generate_additional_parameters(k->rsa); | ||
2566 | break; | ||
2567 | case KEY_RSA_CERT_V00: | ||
2568 | case KEY_RSA_CERT: | ||
2569 | cert = buffer_get_string(blob, &len); | ||
2570 | if ((k = key_from_blob(cert, len)) == NULL) | ||
2571 | fatal("Certificate parse failed"); | ||
2572 | free(cert); | ||
2573 | key_add_private(k); | ||
2574 | buffer_get_bignum2(blob, k->rsa->d); | ||
2575 | buffer_get_bignum2(blob, k->rsa->iqmp); | ||
2576 | buffer_get_bignum2(blob, k->rsa->p); | ||
2577 | buffer_get_bignum2(blob, k->rsa->q); | ||
2578 | break; | ||
2579 | case KEY_ED25519: | ||
2580 | k = key_new_private(type); | ||
2581 | k->ed25519_pk = buffer_get_string(blob, &pklen); | ||
2582 | k->ed25519_sk = buffer_get_string(blob, &sklen); | ||
2583 | if (pklen != ED25519_PK_SZ) | ||
2584 | fatal("%s: ed25519 pklen %d != %d", | ||
2585 | __func__, pklen, ED25519_PK_SZ); | ||
2586 | if (sklen != ED25519_SK_SZ) | ||
2587 | fatal("%s: ed25519 sklen %d != %d", | ||
2588 | __func__, sklen, ED25519_SK_SZ); | ||
2589 | break; | ||
2590 | case KEY_ED25519_CERT: | ||
2591 | cert = buffer_get_string(blob, &len); | ||
2592 | if ((k = key_from_blob(cert, len)) == NULL) | ||
2593 | fatal("Certificate parse failed"); | ||
2594 | free(cert); | ||
2595 | key_add_private(k); | ||
2596 | k->ed25519_pk = buffer_get_string(blob, &pklen); | ||
2597 | k->ed25519_sk = buffer_get_string(blob, &sklen); | ||
2598 | if (pklen != ED25519_PK_SZ) | ||
2599 | fatal("%s: ed25519 pklen %d != %d", | ||
2600 | __func__, pklen, ED25519_PK_SZ); | ||
2601 | if (sklen != ED25519_SK_SZ) | ||
2602 | fatal("%s: ed25519 sklen %d != %d", | ||
2603 | __func__, sklen, ED25519_SK_SZ); | ||
2604 | break; | ||
2605 | default: | ||
2606 | free(type_name); | ||
2607 | buffer_clear(blob); | ||
2608 | return NULL; | ||
2609 | } | ||
2610 | free(type_name); | ||
2611 | |||
2612 | /* enable blinding */ | ||
2613 | switch (k->type) { | ||
2614 | case KEY_RSA: | ||
2615 | case KEY_RSA_CERT_V00: | ||
2616 | case KEY_RSA_CERT: | ||
2617 | case KEY_RSA1: | ||
2618 | if (RSA_blinding_on(k->rsa, NULL) != 1) { | ||
2619 | error("%s: RSA_blinding_on failed", __func__); | ||
2620 | key_free(k); | ||
2621 | return NULL; | ||
2622 | } | ||
2623 | break; | ||
2624 | } | 477 | } |
2625 | return k; | 478 | return 1; |
2626 | } | 479 | } |